☰ INDEX
Abdominal Wall - 1 (Landmarks & Inguinal Canal)
Abdominal Wall - 2 (Rectus Sheath & Thoracolumbar Fascia)
Anterior Compartment of Thigh & Femoral Nerve
Anterior Triangles of The Neck
Aorta, CT, SMA & IMA
Arches of Foot
Arterial Supply of Heart
Ascending Tracts
Auditory Pathway
Basal Ganglia
Bilaminar Germ Disk Formation & Gastrulation
Blood Supply of Brain
Blood Supply of Face
Blood Vessels - Axillary Artery & Anastomosis Around Scapula
Blood Vessels - Brachial Artery - Anastomosis Around Elbow
Blood Vessels of Head, Neck & Face
Brachial Plexus
Brainstem (Ventral & Dorsal View) & IV Ventricles
Brainstem Syndrome
CVS Development - Arterial System
CVS Development - Heart Tube & Derivates
CVS Development - Interatrial & Interventricular Septum
CVS Development - Venous System
Cardiac Plexus, Thoracic Duct, Esophagus & Posterior Mediastinum
Cavernous Sinus
Cerebellum
Cerebral Cortex
Cerebrum - Homunculus, Histology & Diencephalon
Clavipectoral Fascia & Intermuscular Scapular Spaces
Collagen Fibers, Junctional Complexes, Cardiac & Skeletal Muscles & Types of Cartilages
Conus Medullaris & Cauda Equina Syndrome
Cranial Duramater & Dural Venous Sinus
Cranial Nerve - III, IV & VI
Cranial Nerve Nuclei & Columns
Cranial Nerve – VII
Cranial nerves - IX, X, XI & XII Nerves
Cubital Fossa
Deep Cervical Fascia
Descending Tracts
Elbow Joint
Fascia Lata & Modifications
Fertilization & Implantation
Flexor & Extensor Retinaculum
Flexor, Extensor & Peroneal Retinaculum
GIT Development - Foregut
GIT Development - Midgut
Gametogenesis
General Neuroanatomy
Git & Liver Histology
Glands - Parotid Gland
Glands - Thyroid Gland
Gluteal Region
Greymatter - Nuclei & Rexed Laminae
HNF Development - Face & Palate
HNF Development - Pharyngeal Arches
HNF Development - Tongue, Thyroid & Eyeball
Hamstring Compartment & Anastomosis
Heart - External Features
Hindgut & Urogenital System
Inlet Of Thorax & Diaphragm
Interior of Right Atrium & Right Ventricle
Ischiorectal Fossa
Kidney
Larynx
Lateral & Third Ventricles
Leg Compartments
Lining Epithelium
Liver & Hepatic Segments
Lower Limb - Hip Bone
Lower Limb - Tibia & Fibula
Lumbar Plexus
Lungs - Mediastinal Surface & Bronchopulmonary Segments
Medial Compartment of Thigh & Obturator Nerve
Median Nerve
Muscles of Hand
Osteology (Part 1)
Osteology (Part 2)
Osteology - Cranial Cavity
Parasympathetic Ganglion & Cranial Nerve - V
Pericardium & Pericardial Sinuses
Peritoneum
Pharynx
Pleura & Recesses
Popliteal Fossa
Portal Vein & Portacaval Anastomosis
Posterior Triangle of The Neck
Radial Nerve
Sciatic Nerve
Shoulder Joint
Skull - Cranial Cavity
Skull - Norma Basalis
Sole of The Foot
Somites, Lateral Plate Mesoderm & Neural Crest Cells
Spaces in Hand
Spinal Cord - External Features
Subclavian Artery & Scalenous Anterior
Sympathetic Chain - Ramus Communicans
Temporomandibular Joint & Muscles of Mastication
Thalamus & Connections
Thoracic Wall - Muscles, Nerves & Vessels
Ulnar Nerve
Upper Limb - Radius & Ulna
Ureter
Urogenital Triangle
White Matter of Cerebrum (Part 1)
White Matter of Cerebrum (Part 2)
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 32-Year-old male construction worker came to OPD with right-side groin swelling. On examination, cough impulse is positive; Nieman's test shows impulse on the right index finger. Which of the following statement is true about the given patient?", "options": [{"label": "A", "text": "In this type of hernia, the hernial sac passes medial to the Inferior Epigastric Artery.", "correct": false}, {"label": "B", "text": "This type of hernia can occur due to patency of processus vaginalis", "correct": true}, {"label": "C", "text": "This type of hernia has a wider neck of the hernial sac", "correct": false}, {"label": "D", "text": "This type of hernia is common in older men", "correct": false}], "correct_answer": "B. This type of hernia can occur due to patency of processus vaginalis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>This type of hernia can occur due to patency of processus vaginalis The above clinical scenario with Zieman’s test showing impulse on the index finger placed at the deep inguinal ring suggests an Indirect inguinal hernia that can occur due to patent processus vaginalis. The patient given above has an indirect inguinal hernia. Zieman’s test differentiates between indirect(index finger), direct(middle finger), and femoral hernia(ring finger). The swelling is reduced, then the fingers are placed as mentioned above. Later patient is asked to cough. The impulse felt on the specified finger fetches the diagnosis of the type of hernia. Indirect inguinal hernia can occur due to partial or complete patency of the processus vaginalis, an invagination of the peritoneum. Types of indirect inguinal hernia : Bubonocele. The hernia is limited to the inguinal canal. Funicular. The processus vaginalis is closed just above the epididymis. The contents of the sac can be felt separately from the testis, which lies below the hernia. Complete (synonym: scrotal). A full inguinal hernia rarely occurs at birth but is commonly encountered in infancy. It can also occur in adolescence or in adulthood. The testis appears to lie within the lower part of the hernia.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The inferior epigastric artery lies lateral to a direct hernia and medial to an indirect hernia. That means In the indirect inguinal hernia, the hernial sac passes lateral to the inferior epigastric artery, NOT MEDIAL as given in option A Option: C. In an Indirect inguinal hernia, the hernial sac passes through the deep inguinal ring with a small diameter. Thus, this type of hernia has a narrow neck. Direct inguinal hernias are less susceptible to strangulation as they have wide channels than indirect hernias. Option: D. Direct hernia is more common in older age, whereas indirect hernia is common in younger generation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A neonate is admitted to the NICU due to difficulty breathing and cyanosis. On examination, scaphoid abdomen, barrel-shaped chest, and signs of respiratory distress are noted. The radiograph of the baby is shown below. Which of the following is the most probable diagnosis?", "options": [{"label": "A", "text": "Bochdalek Hernia", "correct": true}, {"label": "B", "text": "Acquired hiatus hernia", "correct": false}, {"label": "C", "text": "Morgagni hernia", "correct": false}, {"label": "D", "text": "Horseshoe kidney", "correct": false}], "correct_answer": "A. Bochdalek Hernia", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391565652-QTDA001002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Bochdalek Hernia The above clinical scenario with the image showing bowel loops in the left side of the thoracic cavity suggests Congenital Diaphragmatic Hernia, Bochdalek type. Congenital Diaphragmatic Hernia (CDH) CDH is the herniation of bowel contents into the thoracic cavity due to diaphragm defects. Types - This hernia is congenital. Here, the abdominal contents herniate into the thoracic cavity through the posterolateral hernia of Bochdalek. It is an acute presentation in infants. The symptoms include chest pain and pleural effusion. Adults' most common abdominal symptoms are recurrent abdominal pain, postprandial fullness, and vomiting. By the image, it is the correct answer. A bag and Mask are Contraindicated in such a child.</p>\n<p><strong>Highyeild:</strong></p><p>Bochdalek’s hernia is the most common (85–90%) variety and present with a posterolateral defect (usually left-80%). Morgagni hernia is a rare variety of congenital diaphragmatic hernia and lies anteromedial (usually right) opening in the diaphragm</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Acquired hiatal hernia is the herniation of the cardiac part of the fundus into the thoracic cavity through the esophageal opening. It is either caused due to surgery or obesity. Hence, it is the wrong answer. Option: C. Morgagni hernias are one of the congenital diaphragmatic hernias (CDHs) and are characterized by herniation through the foramen of Morgagni. When compared to Bochdalek hernias, Morgagni hernias tend to be: Anterior More often right-sided (~90%) Small Option: D. Horseshoe kidney is a congenital anomaly of the formation of kidneys. The symptoms include frequent UTIs, infrequent urination, nausea, foul-smelling urine, etc. There are no respiratory symptoms. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Although these hernias have been attributed to failure of the pleuroperitoneal membrane to develop or fuse with the other components of the diaphragm, some authorities believe the primary abnormality is lung hypoplasia, and the herniation of the abdominal contents is secondary</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During surgery to repair a strangulated inguinal hernia, it is discovered that the left testicular vein is thrombosed and must be repaired. The left testicular vein normally drains into which of the following?", "options": [{"label": "A", "text": "Inferior Vena Cava", "correct": false}, {"label": "B", "text": "Left renal vein", "correct": true}, {"label": "C", "text": "Right common iliac vein", "correct": false}, {"label": "D", "text": "Right femoral vein", "correct": false}], "correct_answer": "B. Left renal vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left renal vein The left testicular vein drains into the left renal vein. The inferior vena cava receives the right testicular vein . Thus, left-sided scrotal swelling mandates ruling out left-side RCC The equivalent relationship holds in the female, where the left ovarian vein drains into the left renal vein and the right ovarian vein into the inferior vena cava. The right common iliac, right femoral, and right renal veins do not receive gonadal veins.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A middle-aged obese male patient presents to the emergency room with pain in the inguinal region. Examination reveals an abnormal bulge which increases in size when the patient performs the Valsalva maneuver. The bulge can be reduced manually when the patient is lying supine. However, the bulge reappears as soon as the patient stands up and coughs. The patient is diagnosed with an inguinal hernia. The chief resident in surgery asks to determine whether the hernia is direct or indirect. Which of the following is a useful landmark to distinguish an indirect from a direct inguinal hernia?", "options": [{"label": "A", "text": "Anterior superior iliac spine", "correct": false}, {"label": "B", "text": "Inferior epigastric vessels", "correct": true}, {"label": "C", "text": "Inguinal ligament", "correct": false}, {"label": "D", "text": "Pubic tubercle", "correct": false}], "correct_answer": "B. Inferior epigastric vessels", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior epigastric vessels The inferior epigastric vessels lie medial to the deep inguinal ring . An indirect inguinal hernia leaves the abdominal cavity through the deep inguinal ring and is thus always localized lateral to the inferior epigastric vessels. A direct inguinal hernia results from weakness in the posterior wall of the inguinal canal and pushes through the conjoint tendon to reach the superficial inguinal ring. The direct inguinal hernia is thus always medial to the inferior epigastric vessels. The anterior superior iliac spine and pubic tubercle are respectively located too far laterally or medially to distinguish indirect from direct hernias. The inguinal ligament is used to distinguish a femoral hernia which is always located inferior to this structure. The umbilicus is the site for an umbilical hernia and not inguinal hernias.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 1-day-old infant has a mass protruding through her umbilicus. Physical examination reveals an umbilical hernia. A CT scan reveals that part of another organ is attached to the inner surface of the hernia. What portion of the gastrointestinal tract is most likely to be attached to the inner surface of the umbilical hernia?", "options": [{"label": "A", "text": "Anal Canal", "correct": false}, {"label": "B", "text": "Appendix", "correct": false}, {"label": "C", "text": "Cecum", "correct": false}, {"label": "D", "text": "Ileum", "correct": true}], "correct_answer": "D. Ileum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ileum The ileum is the best answer because it is the most common site of the Meckel diverticulum. This outpouching is a persistence of the vitelline duct and can be attached to the umbilicus. The other answer choices do not correlate with the vitelline duct and will not result in the condition discussed here.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The structure marked (A) in the Image passes through a hiatus in the right crus of the diaphragm. What are the accompanying structures passing through the hiatus along with structure (A)?", "options": [{"label": "A", "text": "Anterior and Posterior Vagal Trunks", "correct": true}, {"label": "B", "text": "Internal Thoracic Vessels", "correct": false}, {"label": "C", "text": "Greater and Lesser Splanchnic Nerves", "correct": false}, {"label": "D", "text": "Right Phrenic Nerve", "correct": false}], "correct_answer": "A. Anterior and Posterior Vagal Trunks", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391566864-QTDA001006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior and Posterior Vagal Trunks Anterior and Posterior Vagal trunks. They pass through the esophageal hiatus at the T10 level along with the esophagus.</p>\n<p><strong>Highyeild:</strong></p><p>Bochdalek’s hernia is the most common (85–90%) variety and present with a posterolateral defect (usually left-80%). Morgagni hernia is a rare variety of congenital diaphragmatic hernia and lies anteromedial (usually right) opening in the diaphragm</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B . Internal Thoracic Vessels pass through the Foramen of Morgagni. Option: C. Greater and Lesser Splanchnic Nerves pass through the minor apertures in the diaphragmatic crura. Option: D. Right Phrenic Nerve passes through the Vena Caval Hiatus at T8 level.</p>\n<p><strong>Extraedge:</strong></p><p>Although these hernias have been attributed to failure of the pleuroperitoneal membrane to develop or fuse with the other components of the diaphragm, some authorities believe the primary abnormality is lung hypoplasia, and the herniation of the abdominal contents is secondary</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 40-year-old male presented with hypertension, type 2 diabetes & sleep apnea with a body mass index (BMI) greater than 40. The surgeon advised him to undergo Bariatric surgery to reduce the gastric volume by plication of the gastric area marked as A in a given image. All of the following ligaments are attached to the greater curvature of the stomach EXCEPT :", "options": [{"label": "A", "text": "Gastrophrenic Ligament", "correct": false}, {"label": "B", "text": "Gastrocolic Ligament", "correct": false}, {"label": "C", "text": "Gastrosplenic Ligament", "correct": false}, {"label": "D", "text": "Lesser Omentum", "correct": true}], "correct_answer": "D. Lesser Omentum", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391566971-QTDA001007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lesser Omentum It is attached to the lower curvature of the stomach, duodenum, and liver inferiorly.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A, B & C . Gastrophrenic, Gastrocolic, and Gastrosplenic ligaments comprise the Greater omentum attached to the greater omentum (structure marked (A)) of the stomach and also to their target organs. Gastrophrenic ligament- Greater curvature to the Diaphragm Gastrocolic ligament- Greater curvature of the colon Gastrosplenic ligament – spleen.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A surgeon has to access the lesser sac for the drainage of fluid. Which of the following structures has to be excised to reach the potential space without damaging any structures?", "options": [{"label": "A", "text": "Transverse Mesocolon", "correct": true}, {"label": "B", "text": "Lesser omentum", "correct": false}, {"label": "C", "text": "Greater omentum", "correct": false}, {"label": "D", "text": "Gastrosplenic ligament", "correct": false}], "correct_answer": "A. Transverse Mesocolon", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Transverse Mesocolon Fluid can accumulate in the lesser sac in ascites and some liver conditions. To excise a peritoneal ligament, one must be careful not to damage the structure present/ enclosed within it. In this case, a transverse mesocolon can be excised on the right side for accessing the lesser sac. Transverse mesocolon is the posterior relation of the lesser sac that suspends the transverse colon from the rear abdominal wall. The excision is done on the left side because the lesser sac is on the left side. Further, an excision on the right side may damage the middle colic artery and the other branches of the superior mesenteric artery that flows on the right side. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Lesser omentum is the anterior relation of the lesser sac, and it contains many vital structures like the left gastric aster and the portal triad. Hence, it can’t be excised and is the wrong answer. Option: C. Greater omentum’s first and last two layers are the anterior and posterior relations of the lesser sac. It has some critical structures, like the gastroepiploic arteries. Further, it is obliterated over time. Hence, it is the wrong answer. Option: D. Gastrosplenic ligament is a peritoneal fold connecting the stomach and the spleen. It has some essential structures, like the splenic vessels and the tail of the pancreas. Hence, it can’t be excised and is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Abdominal aorta branches are organized into paired or unpaired and visceral or parietal branches. Which of the following are paired visceral branches of the abdominal aorta? Suprarenal arteries Gonadal arteries Inferior phrenic arteries Lumbar arteriesRenal arteries Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,2", "correct": false}, {"label": "B", "text": "1,2,5", "correct": true}, {"label": "C", "text": "2,4", "correct": false}, {"label": "D", "text": "1,2,3,", "correct": false}], "correct_answer": "B. 1,2,5", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,2,5 The gonadal arteries are paired with visceral branches of the abdominal aorta. Other branches in this category are the suprarenal and renal arteries. The inferior phrenic and lumbar arteries are paired with parietal branches.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 19 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A middle-aged woman comes to the physician with complaints of abdominal pain. Physical examination shows a slight and mild tenderness and bulging in the linea semilunaris on the right side. No pain is elicited in McBurney's point, and no neoplasm is seen after a biopsy. The colonic biome is satisfactory. There is no history of surgery. Which of the following disorders explains the above symptoms and signs?", "options": [{"label": "A", "text": "Diverticulitis", "correct": false}, {"label": "B", "text": "Richter's hernia", "correct": false}, {"label": "C", "text": "Parastomal hernia", "correct": false}, {"label": "D", "text": "Spigelian hernia", "correct": true}], "correct_answer": "D. Spigelian hernia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spigelian hernia Here, the abdominal contents herniate through the linea semilunaris of the rectus sheath . The hernia is not prominent as the others due to the fibrous nature of the aponeurosis forming the linea semilunaris. Differential diagnosis includes appendicitis, hematoma of the rectus sheath, and diverticulosis. Spigelian hernia is a hernia that occurs through the Spigelian fascia (it is the combined ventral aponeuroses of the external abdominal oblique, internal abdominal oblique, and transversus abdominis muscles). It protrudes to a small extent due to the toughness of the Spigelian fascia along the linea semilunaris. The symptoms include changes in bowel function, constipation, bleeding, and abdominal pain when lifting, coughing, or having a bowel movement. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Diverticulitis is the inflammation of the out pouches seen in diverticulosis. The bacterial biome in the colon will be significantly altered in these cases. But the vignette shows an average bacterial count. Hence, it is the wrong answer. Option: B. Richter’s hernia is a rare type of strangulation that is distinct from the other types of hernia as only one wall of the intestine gets herniated. The common sites of this hernia include the femoral ring, inguinal canal, and incision sites. Hence, it is the wrong answer. Option: C. Parastomal hernia is a type of incisional hernia wherein the abdominal contents herniate through a site of the earlier incision. They commonly occur along the line of alba. Hence, it is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Emergency department surgeons decide to perform an exploratory laparotomy on a 32-year-old female with severe abdominal pain. Where would the incision most likely separate the left and right rectus sheaths?", "options": [{"label": "A", "text": "Midaxillary Line", "correct": false}, {"label": "B", "text": "Arcuate line", "correct": false}, {"label": "C", "text": "Semilunar line", "correct": false}, {"label": "D", "text": "Linea alba", "correct": true}], "correct_answer": "D. Linea alba", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Linea alba The linea alba is formed by the intersection of aponeurotic tissues between the right and left rectus abdominal muscles. It contains the aponeuroses of the abdominal muscles and is located at the body's midline.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The midaxillary line is oriented vertically in a straight line inferior to the shoulder joint and axilla. Option: B. The arcuate line (of Douglas) is a curved horizontal line representing the lower edge of the posterior tendinous portion of the rectus abdominis sheath. An incision at this line will not separate the rectus abdominis sheaths. Option: C. The semilunar line is represented by an imaginary vertical line below the nipples and usually parallels the lateral edge of the rectus sheath.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 35-year-old man is admitted to the hospital with an indirect inguinal hernia. During an open hernioplasty (in contrast to a laparoscopic procedure), the spermatic cord and the internal abdominal oblique muscles are identified. Which component of the spermatic cord is derived from the internal oblique muscle?", "options": [{"label": "A", "text": "External Spermatic Fascia", "correct": false}, {"label": "B", "text": "Cremaster muscle", "correct": true}, {"label": "C", "text": "Tunica vaginalis", "correct": false}, {"label": "D", "text": "Internal spermatic fascia", "correct": false}], "correct_answer": "B. Cremaster muscle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cremaster muscle The cremaster muscle and fascia originate from the internal oblique muscle. The contents of the spermatic cord include ductus deferens; testicular, cremasteric, and deferential arteries; the pampiniform plexus of testicular veins; the genital branch of the genitofemoral nerve; the cremasteric nerves; and the sympathetic testicular plexus and also lymph vessels.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "After a mastectomy, a musculocutaneous flap is used to restore the thoracic contour in a 34-year-old female patient. The ipsilateral (same side) rectus abdominis muscle was detached carefully from the surrounding structures and transposed to the thoracic wall. Which of the following landmarks is most often used to locate the low end of the posterior, tendinous layer of the rectus sheath?", "options": [{"label": "A", "text": "Intercristal Line", "correct": false}, {"label": "B", "text": "Linea alba", "correct": false}, {"label": "C", "text": "Arcuate line", "correct": true}, {"label": "D", "text": "Pectineal line", "correct": false}], "correct_answer": "C. Arcuate line", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Arcuate line The arcuate line is a horizontal line that demarcates the lower limit of the posterior aponeurotic portion of the rectus sheath. It is also where the inferior epigastric vessels perforate the sheath to enter the rectus abdominis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The intercristal line is an imaginary line drawn in the horizontal plane at the upper margin of the iliac crests. Option: B. The linea alba is a tendinous, median raphe running vertically between the two rectus abdominis muscles from the xiphoid process to the pubic symphysis. Option: D. The pectineal line is a feature of the superior ramus of the pubic bone; it provides an origin for the pectineus muscle of the thigh and medial insertions for the abdominal obliques and transverses muscles.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 57-year-old man was admitted to the emergency department with left flank pain. Blood tests indicate hematuria and anemia. An MRI scan reveals that blood flow in the left renal vein is impeded by an arterial aneurysm where the vein crosses the aorta. The aneurysm is most likely located in which of the following arteries?", "options": [{"label": "A", "text": "Celiac", "correct": false}, {"label": "B", "text": "Inferior mesenteric", "correct": false}, {"label": "C", "text": "Left colic", "correct": false}, {"label": "D", "text": "Superior mesenteric", "correct": true}], "correct_answer": "D. Superior mesenteric", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior mesenteric T he superior mesenteric artery lies superior and anterior to the left renal vein as the vein terminates in the inferior vena cava.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The celiac artery is located superiorly and would not compress the left renal vein. Option: B & C. The inferior mesenteric artery and its left colic branch are located too inferiorly to occlude the left renal vein.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 22-year-old man is admitted to the emergency department with acute abdominal pain in his right lower quadrant. Radiographic and physical examinations provide evidence of acute appendicitis. An appendectomy begins with an incision at McBurney's point. Which of the following abdominal layers must the surgeon pass to reach the appendix through this incision?", "options": [{"label": "A", "text": "External abdominal oblique muscle, internal oblique muscle, transversalis fascia, and parietal peritoneum", "correct": false}, {"label": "B", "text": "Aponeurosis of the external abdominal oblique muscle, internal oblique muscle, transversus abdominis muscle, transversalis fascia, and parietal peritoneum", "correct": true}, {"label": "C", "text": "Aponeurosis of the external abdominal oblique muscle, internal oblique muscle, transversus abdominis muscle, and parietal peritoneum", "correct": false}, {"label": "D", "text": "Aponeurosis of the external abdominal oblique muscle, aponeurosis of internal oblique muscle, transversus abdominis muscle, transversalis fascia, and parietal peritoneum", "correct": false}], "correct_answer": "B. Aponeurosis of the external abdominal oblique muscle, internal oblique muscle, transversus abdominis muscle, transversalis fascia, and parietal peritoneum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Aponeurosis of the external abdominal oblique muscle, internal oblique muscle, transversus abdominis muscle, transversalis fascia, and parietal peritoneum The incision and tissue separation at McBurney’s point to reach the appendix will usually encounter the aponeurosis of the external abdominal oblique muscle, internal oblique muscle, transversus abdominis muscle, transversalis fascia, and parietal peritoneum. Muscle fibers of the internal oblique and transversus can be separated bluntly without cutting them. Thus, five layers must be penetrated to access the inflamed appendix. The appendix is located intraperitoneally within the abdomen, thus it is covered by the visceral peritoneum. The transversalis fascia separates the internal surface of the transversus abdominis from the parietal peritoneum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statements are true regarding Iliolumbar ligament Attached to the transverse process of L4 Lower part attached to the sacrospinous ligament Attached to the iliac crest Upper part continuous with the thoracolumbar fascia Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1, 2", "correct": false}, {"label": "B", "text": "1, 3, 4", "correct": true}, {"label": "C", "text": "1,4", "correct": false}, {"label": "D", "text": "2, 4", "correct": false}], "correct_answer": "B. 1, 3, 4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1, 3, 4 (Attached to the transverse process of L4, Attached to the iliac crest, Upper part continuous with the thoracolumbar fascia) The iliolumbar ligament is the major ligament associated with the lumbosacral junction. It is attached to the tip of the anteroinferior aspect of the transverse process of the fifth lumbar vertebrae and occasionally to the transverse process of the fourth lumbar vertebrae. It has two parts – the upper part and the lower part The upper part is attached to the iliac crest anterior to the sacroiliac joint and is continuous above the anterior layer of the thoracolumbar fascia. The lower part reaches the posterior part of the iliac fossa and blends with the anterior sacroiliac ligament. The iliolumbar ligament contributes to the anterior stability of sacroiliac joints.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 52-year-old male underwent an appendectomy three months back. Now he has come to the OPD with a complaint of loss sensation over the skin of the suprapubic area. Which nerve might have been injured during the procedure?", "options": [{"label": "A", "text": "Femoral Nerve", "correct": false}, {"label": "B", "text": "Iliohypogastric nerve", "correct": true}, {"label": "C", "text": "Ilioinguinal nerve", "correct": false}, {"label": "D", "text": "Pudendal nerve", "correct": false}], "correct_answer": "B. Iliohypogastric nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Iliohypogastric nerve The iliohypogastric nerve passes medially to the anterosuperior iliac spine in the abdominal wall to supply the skin of the suprapubic area. It enters the anterior abdominal wall at a site 2–3 cm medial to the anterosuperior iliac spine and then courses between the layers of the rectus sheath. It is at risk for entrapment when closing a low transverse incision.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The femoral nerve provides sensory innervation to the anterior thigh's skin and the leg's anteromedial aspect. Option: C. The ilioinguinal nerve arises from the anterior ramus of the L1 nerve root from the lumbar plexus along with the iliohypogastric nerve. The predominantly sensory nerve eventually passes through the superficial inguinal ring to provide cutaneous sensation to the upper medial thigh, mons pubis, and labium majus in women. Option: D. The pudendal nerve is the main nerve of the perineum. It carries sensation from the external genitalia of both sexes and the skin around the anus and perineum, as well as the motor supply to various pelvic muscles, including the female external urethral sphincter and the external anal sphincter.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 18 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Your young female patient has a large bulge on the anterior thigh below the inguinal ligament. You suspect an abdominal hernia that has passed through the femoral ring into the femoral sheath and then through the saphenous hiatus into the subcutaneous layer of the upper thigh. In addition to the hernial sac, you would expect the femoral canal to contain which of the following?", "options": [{"label": "A", "text": "Connective tissue and lymph nodes", "correct": true}, {"label": "B", "text": "Femoral artery", "correct": false}, {"label": "C", "text": "Femoral nerve", "correct": false}, {"label": "D", "text": "Femoral vein", "correct": false}], "correct_answer": "A. Connective tissue and lymph nodes", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Connective tissue and lymph nodes The femoral canal is the medial and smallest compartment of the three compartments of the femoral sheath. It is conical in shape. The femoral canal contains lymphatic vessels, and adipose loose connective tissue, and deep inguinal lymph nodes. The function of the femoral canal is to accommodate the distension of the femoral vein when venous return from the leg is increased or temporarily restricted. Femoral sheath</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. The femoral artery is found in the lateral compartment of the femoral sheath with the genital branch of the genitofemoral nerve. Option: C. The femoral nerve is the most lateral structure in the femoral triangle , but it does not lie within the femoral sheath. Option: D. The femoral vein occupies the intermediate compartment of the femoral sheath . The saphenous vein is a superficial vein that passes through the saphenous hiatus to end in the femoral vein. It does not lie within the femoral canal.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In elderly patients (over 60 years of age), fractures of the neck of the femur following a fall are common. Arterial branches supplying the femoral head and neck are vulnerable to injury during these fractures, and the resulting post-traumatic avascular necrosis affects the head of the femur. In the adult, the most important direct vascular source to the femoral head and neck is which of the following?", "options": [{"label": "A", "text": "Artery to the head of the femur", "correct": false}, {"label": "B", "text": "Femoral artery", "correct": false}, {"label": "C", "text": "Lateral circumflex femoral artery", "correct": false}, {"label": "D", "text": "Medial circumflex femoral artery", "correct": true}], "correct_answer": "D. Medial circumflex femoral artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Medial circumflex femoral artery The medial circumflex femoral artery is an artery in the upper thigh that arises from the profunda femoris artery . It supplies arterial blood to several muscles in the region, as well as the femoral head and neck. Damage to the artery following a femoral neck fracture may lead to avascular necrosis (ischemic) of the femoral neck/head.</p>\n<p><strong>Highyeild:</strong></p><p>Medial Circumflex femoral artery ' The medial circumflex femoral artery supplies the most important source of blood to the femoral head and neck.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Artery to the head of the femur Artery to the head of the femur, which arises from the obturator artery. However, if the medial circumflex femoral artery is injured, the blood flow in the small artery to the head of the femur may not be sufficient to prevent post-traumatic avascular necrosis of the femoral head. Option: B. Femoral artery Normally, the medial and lateral circumflex femoral arteries arise from the deep artery of the thigh, but occasionally they arise from the femoral artery. However, the femoral artery is not a direct vascular source to the head of the femur. Option: C. Lateral circumflex femoral artery The lateral circumflex femoral artery and superior gluteal artery also supply the hip joint, but their contribution to the head and neck of the femur is less than that of the medial femoral circumflex artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 34-year-old woman has a direct blow to the patella by the dashboard of a vehicle during an automobile crash. The woman is admitted to the emergency department and radiographic examination reveals patellofemoral syndrome. This type of syndrome is characterized by lateral dislocation of the patella. Which of the following muscles requires strengthening by physical rehabilitation to prevent future dislocation of the patella?", "options": [{"label": "A", "text": "Vastus Lateralis", "correct": false}, {"label": "B", "text": "Vastus medius", "correct": true}, {"label": "C", "text": "Vastus intermedius", "correct": false}, {"label": "D", "text": "Rectus femoris", "correct": false}], "correct_answer": "B. Vastus medius", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Vastus medius During the extension of the knee joint, there is a natural tendency of the patella to dislocate laterally. The vastus medialis inserts upon the medial aspect of the patella and draws it medially , especially in the last quarter of extension- during which it is especially palpable in contraction. This muscle is referred to as the vastus medialis obliquus (VMO). Increasing the strength of this muscle can lessen the lateral dislocation of the patella.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: Option: A. Vastus Lateralis Option: C. Vastus intermedius Option: D. Rectus femoris Vastus lateralis , Vastus intermedius, and Rectus femoris are not involved in further prevention of lateral dislocation of the Patella.</p>\n<p><strong>Extraedge:</strong></p><p>Thus the main dynamic stabilizer of the patella is the vastus medialis obliquus (VMO) muscle. This is the most distal portion of the quadriceps muscle and exerts a medially directed pull which helps maintain the patella well positioned . Weakness or dysplasia of this muscle increases the risk of dislocations.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient experiences paralysis of the muscle that originates from the femur and contributes directly to the stability of the knee joint. Which of the following muscles is involved?", "options": [{"label": "A", "text": "Vastus Lateralis", "correct": true}, {"label": "B", "text": "Semimembranosus", "correct": false}, {"label": "C", "text": "Sartorius", "correct": false}, {"label": "D", "text": "Biceps femoris( long head)", "correct": false}], "correct_answer": "A. Vastus Lateralis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Vastus Lateralis All the muscles given in the options are contributing to the stability of the knee joint but the vastus lateralis muscles arise from the femur and all other muscles originate from the hip (coxal) bone.</p>\n<p><strong>Highyeild:</strong></p><p>Vastus Lateralis Origin The superior portion of the intertrochanteric line, anterior and inferior borders of the greater trochanter, superior portion of lateral lip of linea aspera, and lateral portion of gluteal tuberosity of femur Insertion The lateral base and border of the patella; also form the lateral patellar retinaculum and lateral side of the quadriceps femoris tendon Action Extends the knee Innervation Muscular branches of the femoral nerve (L2, L3, L4)</p>\n<p><strong>Random:</strong></p><p>Option: B. Semimembranosus Semimembranous originates from the hip bone. ● Origin ● Superior lateral quadrant of the ischial tuberosity ● Insertion ● The posterior surface of the medial tibial condyle ● Action ● Extends the thigh, flexes the knee, and also rotates the tibia medially, especially when the knee is flexed ● Innervation ● Tibial nerve (L5, S1, S2) ● Arterial Supply ● Perforating branches of profunda femoris artery, inferior gluteal artery, and the superior muscular branches of the popliteal artery Option: C. Sartorius Sartorius originates from the hip bone. ● Origin ● Anterior superior iliac spine ● Insertion ● The superior aspect of the medial surface of the tibial shaft near the tibial tuberosity (joins gracilis and semitendinosus at the pes anserinus) ● Action ● Flexes and laterally rotates the hip joint and flexes the knee ● Innervation ● Femoral nerve (L2, L3, L4) ● Arterial Supply ● Muscular branches of the femoral artery Option: D. Biceps femoris ( long head) The biceps femoris long head originates from the hip bone. ● Origin ● Superior medial quadrant of the posterior portion of the ischial tuberosity ● Insertion ● Primarily on the fibular head; also on the lateral collateral ligament and lateral tibial condyle ● Action ● Flexes the knee, and also rotates the tibia laterally; the long head also extends the hip joint ● Innervation ● Tibial nerve (L5, S1, S2) ● Arterial supply ● Perforating branches of profunda femoris artery, inferior gluteal artery, and the superior muscular branches of the popliteal artery</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 24-year-old woman presents to her physician with weakness in flexing the hip joint and extending the knee joint. Which muscle is most likely involved in this scenario?", "options": [{"label": "A", "text": "Sartorius", "correct": false}, {"label": "B", "text": "Gracilis", "correct": false}, {"label": "C", "text": "Rectus femoris", "correct": true}, {"label": "D", "text": "Vastus medialis", "correct": false}], "correct_answer": "C. Rectus femoris", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Rectus femoris The rectus femoris flexes the thigh and extends the leg.</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options:- Option: A. Sartorius The sartorius can flex both the hip and knee joints. Option: B. Gracilis The gracilis adducts and flexes the thigh and flexes the leg. Option: D. Vastus medialis The vastus medialis extends the knee joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which statement correctly describes the anterior compartment of the leg?", "options": [{"label": "A", "text": "It is separated from the posterior compartment by the anterior intermuscular septum.", "correct": false}, {"label": "B", "text": "All the muscles of the compartment are innervated by the superficial peroneal nerve.", "correct": false}, {"label": "C", "text": "The anterior tibial artery arises in the anterior compartment.", "correct": false}, {"label": "D", "text": "It contains peroneus tertius.", "correct": true}], "correct_answer": "D. It contains peroneus tertius.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>It contains peroneus tertius. Option: D. It contains peroneus tertius. The anterior compartment contains the tibialis anterior, extensor hallucis longus, extensor digitorum longus, and fibularis tertius muscles , innervated by the deep peroneal nerve and supplied by the anterior tibial artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect Options: Option: A. It is separated from the posterior compartment by the anterior intermuscular septum. The anterior compartment of the leg is separated from the lateral compartment by the anterior intermuscular septum. The anterior and posterior compartments are separated by the tibia, the fibula, and the interosseous membrane. Option: B. All the muscles of the compartment are innervated by the superficial peroneal nerve. All muscles of the anterior compartments (tibialis anterior, extensor digitorum longus, extensor hallucis longus, and peroneus tertius) are innervated by deep peroneal nerve. Option: C. The anterior tibial artery arises in the anterior compartment. The anterior tibial artery arises from the popliteal artery in the posterior compartment and then becomes the dorsalis pedis artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 2-year-old male patient develops progressive generalized weakness and muscle atrophy. First began with the muscles of the hips, and then progressed to the pelvic area, thigh, and shoulder muscles. He is diagnosed with Duchenne’s muscular dystrophy, a congenital disorder where the protein dystrophin is deficient. Which of the following describes the role of dystrophin in muscle tissue?", "options": [{"label": "A", "text": "Anchors actin on the sarcolemma", "correct": true}, {"label": "B", "text": "Endows the myosin filaments with elastic recoil properties", "correct": false}, {"label": "C", "text": "Extends from Z disk to Z disk, forming a supportive network", "correct": false}, {"label": "D", "text": "Inhibits the binding of myosin to actin", "correct": false}], "correct_answer": "A. Anchors actin on the sarcolemma", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anchors actin on the sarcolemma Dystrophin anchors actin to the sarcolemma , reinforcing and stabilizing it during muscle contraction.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Endows the myosin filaments with elastic recoil properties Titin is a large protein that associates with myosin filaments and endows them with elastic recoil properties. Option: C. Extends from Z disk to Z disk, forming a supportive network Desmin filaments form a supportive network extending from Z disk to Z disk. Option: D. Inhibits the binding of myosin to actin Troponin I inhibits the binding of myosin to actin. Alpha B-crystallin protects desmin filaments from stress-induced damage.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 75-year-old man is transported to the casualty with severe pain in his right hip and thigh. A radiographic examination reveals avascular necrosis of the femoral head (Image). Which of the following conditions most likely occurred to produce avascular necrosis in this patient?", "options": [{"label": "A", "text": "Dislocation of the hip with tearing of the ligament of the head of the femur", "correct": false}, {"label": "B", "text": "Intertrochanteric fracture of the femur", "correct": false}, {"label": "C", "text": "Intracapsular femoral neck fracture", "correct": true}, {"label": "D", "text": "Thrombosis of the obturator artery", "correct": false}], "correct_answer": "C. Intracapsular femoral neck fracture", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681861984-QTDA037008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Intracapsular femoral neck fracture An intracapsular femoral neck fracture causes avascular necrosis of the femoral head because the fracture damages the radicular branches of the medial and lateral circumflex arteries that pass beneath the ischiofemoral ligament and pierce the femoral neck.</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect options: Option: A. Dislocation of the hip with tearing of the ligament of the head of the femur Until an individual reaches about 6 to 10 years of age, the blood supply to the head of the femur is provided by a branch of the obturator artery that runs with the ligament of the head of the femur. Thereafter, the ligament of the head of the femur is insignificant. Option: B. Intertrochanteric fracture of the femur Intertrochanteric fracture of the femur would not damage the blood supply to the head of the femur but would cause complications because the greater trochanter is an attachment site for several gluteal muscles. Option: D. Thrombosis of the obturator artery During childhood, the obturator artery provides the artery of the ligament of the head of the femur. Thrombosis of the obturator artery could result in muscular symptoms, although there are several collateral sources of blood supply in the thigh. A comminuted fracture of the extracapsular femoral neck would not ordinarily imperil the vascular supply.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "What is true about the adductors of the thigh?", "options": [{"label": "A", "text": "Ischial head of adductor magnus is an adductor", "correct": false}, {"label": "B", "text": "Popliteal artery is the main blood supply", "correct": false}, {"label": "C", "text": "Ischial head of adductor magnus originates from adductor tubercle", "correct": false}, {"label": "D", "text": "Adductor magnus is the largest muscle", "correct": true}], "correct_answer": "D. Adductor magnus is the largest muscle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Adductor magnus is the largest muscle The adductor magnus is the largest and strongest muscle of the medial compartment.</p>\n<p><strong>Highyeild:</strong></p><p>Adductor Magnus Origin Adductor part: Inferior pubic ramus, ischial ramusIschiocondylar part: Ischial tuberosity Insertion Adductor part: Gluteal tuberosity, linea aspera (medial lip), medial supracondylar lineIschiocondylar part: Adductor tubercle of femur Action Adductor part:Hip joint - Thigh flexion, thigh adduction, thigh external rotationHamstring part:Hip joint - Thigh extension, thigh internal rotationEntire muscle: Pelvis stabilization Innervation Adductor part: Obturator nerve (L2-L4)Ischiocondylar part: Tibial division of sciatic nerve (L4)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Ischial head of adductor magnus is an adductor The posterior ischial head of adductor magnus, takes origin from ischial tuberosity and is a hamstring part( not adductor) Option: B. Popliteal artery is the main blood supply The profunda femoris artery provides a major supply to all three compartments of the thigh including the medial (adductor) compartment. Option: C. Ischial head of adductor magnus originates from adductor tubercle The adductor tubercle receives the insertion( not the origin) of adductor magnus</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which muscle in the anterior compartment of the thigh is usually attached to the synovial membrane?", "options": [{"label": "A", "text": "Rectus Femoris", "correct": false}, {"label": "B", "text": "Articularis genu", "correct": true}, {"label": "C", "text": "Sartorius", "correct": false}, {"label": "D", "text": "Vastus lateralis", "correct": false}], "correct_answer": "B. Articularis genu", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Articularis genu It attaches to the proximal part of the synovial membrane of the knee joint thus pulls the synovial membrane upwards during extension of the knee.</p>\n<p><strong>Highyeild:</strong></p><p>Articularis Genu Origin femur Insertion suprapatellar bursa Artery femoral artery Nerve femoral nerve Actions Pulling the suprapatellar bursa during extension of the knee</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Rectus femoris Rectus femoris: It is attached to the base of the patella and it causes extension of the knee. Rectus Femoris Origin anterior inferior iliac spine and the exterior surface of the bony ridge which forms the groove on the iliac portion of the acetabulum Insertion inserts into the patellar tendon as one of the four quadriceps muscles Artery descending branch of the lateral femoral circumflex artery Nerve femoral nerve Actions knee extension, Hip Flexion Option: D. Vastus lateralis Vastus Lateralis Origin The superior portion of the intertrochanteric line, anterior and inferior borders of the greater trochanter, superior portion of lateral lip of linea aspera, and lateral portion of gluteal tuberosity of femur ● Insertion The lateral base and border of patella; also forms the lateral patellar retinaculum and lateral side of the quadriceps femoris tendon ● Action Extends the knee ● Innervation Muscular branches of the femoral nerve (L2, L3, L4) Option: C. Sartorius ● Origin ● Anterior superior iliac spine ● ● Insertion ● The superior aspect of the medial surface of the tibial shaft near the tibial tuberosity (joins gracilis and semitendinosus at the pes anserinus) ● ● Action ● Flexes and laterally rotates the hip joint and flexes the knee ● ● Innervation ● Femoral nerve (L2, L3, L4) ● ● Arterial Supply ● Muscular branches of the femoral artery</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following muscle in the anterior compartment of the thigh is supplied by the anterior division of the femoral nerve?", "options": [{"label": "A", "text": "Rectus Femoris", "correct": false}, {"label": "B", "text": "Articularis genu", "correct": false}, {"label": "C", "text": "Sartorius", "correct": true}, {"label": "D", "text": "Vastus medialis", "correct": false}], "correct_answer": "C. Sartorius", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sartorius Sartorius is the muscle supplied by the Anterior division of the femoral nerve. It goes from ASIS to the superomedial surface of the tibia.</p>\n<p><strong>Highyeild:</strong></p><p>Sartorius ● Origin ● Anterior superior iliac spine ● Insertion ● The superior aspect of the medial surface of the tibial shaft near the tibial tuberosity (joins gracilis and semitendinosus at the pes anserinus) ● Action ● Flexes and laterally rotates the hip joint and flexes the knee ● Innervation ● Femoral nerve (L2, L3, L4) ● Arterial Supply ● Muscular branches of the femoral artery</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Rectus Femoris The four motor branches of the posterior division of the femoral nerve are nerves to the rectus femoris, vastus medialis, vastus intermedius, and vastus lateralis . These muscles are the principal extensors of the leg at the knee and collectively form the quadriceps femoris muscle. Option: B. Articularis genu The Articularis genu is a small flat muscle of the anterior knee. During knee extension, it acts to tighten the synovial membrane superiorly thereby preventing impingement of the synovial folds between the femur and the patella, and is innervated by posterior division of the femoral nerve. Option: D. Vastus medialis The four motor branches of the posterior division of the femoral nerve are nerves to the rectus femoris, vastus medialis, vastus intermedius, and vastus lateralis . These muscles are the principal extensors of the leg at the knee and collectively form the quadriceps femoris muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which muscle of the anterior compartment of the thigh causes flexion at the knee joint?", "options": [{"label": "A", "text": "Rectus Femoris", "correct": false}, {"label": "B", "text": "Articularis genu", "correct": false}, {"label": "C", "text": "Vastus lateralis", "correct": false}, {"label": "D", "text": "Sartorius", "correct": true}], "correct_answer": "D. Sartorius", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sartorius The sartorius muscle causes flexion, abduction, and lateral rotation of the hip and flexes the leg at the knee joint.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Rectus Femoris Option: B. Articularis genu Option: C. Vastus lateralis</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which branch of the femoral nerve supplies skin as well as the medial side of the knee?", "options": [{"label": "A", "text": "Anterior branch of the medial femoral cutaneous nerve of thigh", "correct": true}, {"label": "B", "text": "Posterior branch of the medial femoral cutaneous nerve of thigh", "correct": false}, {"label": "C", "text": "Intermediate femoral cutaneous nerve of thigh", "correct": false}, {"label": "D", "text": "Vascular branch", "correct": false}], "correct_answer": "A. Anterior branch of the medial femoral cutaneous nerve of thigh", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior branch of the medial femoral cutaneous nerve of thigh Anterior branch descends on sartorius, perforates the fascia lata beyond mid-thigh, and divides into a branch that supplies the skin as low as the medial side of the knee, and another that runs lateral to the former and connects with the infrapatellar branch of the saphenous nerve.</p>\n<p><strong>Random:</strong></p><p>' Explanation for incorrect options:- Option: B. Posterior branch of the medial femoral cutaneous nerve of thigh Option: C . Intermediate femoral cutaneous nerve of thigh Option: D. Vascular branch Options B, C, and D. do not innervate the medial aspect of the knee.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which muscle is part of the quadriceps femoris?", "options": [{"label": "A", "text": "Pectineus", "correct": false}, {"label": "B", "text": "Vastus intermedius", "correct": true}, {"label": "C", "text": "Gracilis", "correct": false}, {"label": "D", "text": "Sartorius", "correct": false}], "correct_answer": "B. Vastus intermedius", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Vastus intermedius The quadriceps femoris muscle, commonly known as the quad muscle, is the strongest muscle in the human body. It is located in the anterior compartment of the thigh , together with the sartorius . The quadriceps femoris muscle is called a “four-headed muscle”. It bears this name because it consists of four individual muscles; rectus femoris, vastus medialis, vastus lateralis, and vastus intermedius . Out of all four muscles, only the rectus femoris crosses both the hip and knee joints . The others cross only the knee joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 24 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 23-year-old male basketball player is admitted to the hospital after injuring his shoulder during a game. Physical and radiographic examinations reveal total separation of the shoulder. Which of the following structures has most likely been torn?", "options": [{"label": "A", "text": "Glenohumeral Ligament", "correct": false}, {"label": "B", "text": "Coracoacromial ligament", "correct": false}, {"label": "C", "text": "Tendon of long head of biceps brachii", "correct": false}, {"label": "D", "text": "Acromioclavicular ligament", "correct": true}], "correct_answer": "D. Acromioclavicular ligament", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Acromioclavicular ligament The acromioclavicular ligament connects the clavicle to the coracoid process of the scapula . Separation of the shoulder (dislocation of the acromioclavicular [AC] joint) is associated with damage to the acromioclavicular ligament (capsule of the AC joint) and, in more severe injuries, disruption of the coracoclavicular ligaments (conoid and trapezoid portions). The glenohumeral ligament may be injured by an anterior dislocation of the humerus but is not likely to be injured by a separated shoulder. The coracoacromial ligament, transverse scapular ligament, and tendon of the long head of triceps brachii are not likely to be injured by separation of the shoulder</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 69-year-old man has numbness in the middle three digits of his right hand and finds it difficult to grasp objects with that hand. He stated that he retired 9 years earlier, after working as a carpenter for 50 years. He has atrophy of the thenar eminence (Image). Which of the following conditions is the most likely cause of the problems in his hand?", "options": [{"label": "A", "text": "Compression of the median nerve in the carpal tunnel", "correct": true}, {"label": "B", "text": "Formation of the osteophytes that compress the ulnar nerve at the medial epicondyle", "correct": false}, {"label": "C", "text": "Hypertrophy of the triceps muscle compressing the brachial plexus", "correct": false}, {"label": "D", "text": "Osteoarthritis of the cervical spine", "correct": false}], "correct_answer": "A. Compression of the median nerve in the carpal tunnel", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392292862-QTDA015002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Compression of the median nerve in the carpal tunnel The median nerve also provides motor innervation to muscles of the thenar eminence. The median nerve supplies sensory innervation to the thumb, index, and middle fingers and to the ring finger's lateral half. Compression of the median nerve in the carpal tunnel explains these deficits in conjunction with the normal functioning of the flexor compartment of the forearm because these muscles are innervated by the median nerve proximal to the carpal tunnel. The ulnar nerve is not implicated in these symptoms. It does not provide sensation to digits 1 to 3. Compression of the brachial plexus could not be attributed to pressure from the triceps because this muscle is located distal to the plexus. In addition, brachial plexus symptoms would include other upper limb deficits rather than the focal symptoms described in this case. Osteoarthritis of the cervical spine would also lead to increasing complexity of symptoms.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "On both sides submental triangle is bounded by:", "options": [{"label": "A", "text": "Hyoid Bone", "correct": false}, {"label": "B", "text": "Anterior digastric", "correct": true}, {"label": "C", "text": "Posterior digastric", "correct": false}, {"label": "D", "text": "Mylohyoid", "correct": false}], "correct_answer": "B. Anterior digastric", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior digastric SUBMENTAL TRIANGLE This is a median triangle. It is bounded as follows. On each side, there is the anterior belly of the corresponding digastric muscles. The body of the hyoid bone forms its base. Its apex lies at the chin. The floor of the triangle is formed by the right and left mylohyoid muscles and the median raphe uniting them. Contents Two to four small submental lymph nodes are situated in the superficial fascia between the anterior bellies of the digastric muscles. Small submental veins join to form the anterior jugular veins.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following are true about cervical fascia? Pre vertebral fascia contributes to axillary sheath Pre tracheal fascia is continuous with buccopharyngeal fascia Pre vertebral fascia forms the roof of posterior triangle Pharyngobasilar fascia lies deep to the pharyngeal muscles Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,2,3", "correct": false}, {"label": "B", "text": "1,2", "correct": false}, {"label": "C", "text": "2,3,4", "correct": false}, {"label": "D", "text": "1,2,4", "correct": true}], "correct_answer": "D. 1,2,4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,2,4 The deep fascia of the neck is condensed to form the following layers: Investing layer Pretracheal fascia Prevertebral fascia Carotid sheath Buccopharyngeal fascia Pharyngobasilar fascia. INVESTING LAYER It lies deep to the platysma, and surrounds the neck like a collar. It forms the roof of the posterior triangle of the neck. PRETRACHEAL FASCIA The importance of this fascia is that it encloses and suspends the thyroid gland and forms its false capsule. It is continuous with buccopharyngeal fascia. PREVERTEBRAL FASCIA It lies in front of the prevertebral muscles, and forms the floor of the posterior triangle of the neck. As the trunks of the brachial plexus and the subclavian artery pass laterally through the interval between the scalenus anterior and the scalenus medius, they carry with them a covering of the prevertebral fascia known as the axillary sheath which extends into the axilla. CAROTID SHEATH It is a condensation of the fibroareolar tissue around the main vessels of the neck. BUCCOPHARYNGEAL FASCIA This fascia covers all the constrictor muscles externally and extends onto the superficial aspect of the buccinator muscle. PHARYNGOBASILAR FASCIA This fascia is especially thickened between the upper border of superior constrictor muscle and the base of the skull. It lies deep to the pharyngeal muscles.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Infections from which of the following areas marked in the Image can pass down to the posterior mediastinum:", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": true}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "C. C", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392293792-QTDA015005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C The area marked as C is known as the dangerous space of the neck; the danger space lies between the alar and prevertebral fascia and extends from the skull base down to the posterior mediastinum, where the alar, visceral and prevertebral layers of deep cervical fascia fuse. The potential space so created is closed superiorly, inferiorly and laterally; infections can only enter by penetrating its walls. The danger space is so called because its loose areolar tissue offers a potential route for the rapid downward spread of infection, primarily from the retropharyngeal, parapharyngeal or prevertebral spaces, to the posterior mediastinum. = Prevertebral Space = Retropharyngeal Space = Pretracheal Space Prevertebral tissue space is the potential space between the prevertebral fascia and the vertebral column. It extends from the skull base to the coccyx and encloses the prevertebral muscles. Almost all pathology affecting the prevertebral space arises from either the adjacent vertebrae or their intervertebral discs or the spinal cord and associated nerve roots and spinal nerves. Tuberculosis of the spine may breach the space and form a Pott’s abscess. The posterior visceral space is often called the retropharyngeal space in the upper neck. The posterior visceral space lies posterior to the pharynx and cervical oesophagus, extending from the skull base down to the superior mediastinum, its caudal limit being the fusion level between the alar and visceral layers of fascia. Pretracheal Space is also known as anterior visceral space. The visceral division of the middle layer of deep cervical fascia encloses the anterior visceral space, a surgical and radiological term also traditionally (and confusingly) called the ‘pretracheal’ space. It contains the trachea, the thyroid and parathyroid glands, the larynx, the cervical oesophagus, recurrent laryngeal nerves and the cranial sympathetic trunks. The space extends superiorly from the hyoid bone and the attachments of the strap muscles and their fasciae to the hyoid bone and thyroid cartilage down into the anterior portion of the superior mediastinum. It communicates freely with the posterior visceral space around the sides of the larynx, the caudal portion of the pharynx and the upper cervical oesophagus but becomes separated from the posterior visceral space at lower levels by dense connective tissue associated with the inferior thyroid artery as the latter approaches the thyroid gland. Infection usually spreads into the anterior visceral space by either perforation of the anterior wall of the oesophagus by endoscopic instrumentation, foreign bodies or trauma or from the posterior visceral space. Radiologically, the portion of the anterior visceral space between the strap fascia and the fascia of the thyroid gland is referred to as the anterior cervical space; its posterolateral border is either the carotid sheath or the fascia covering the sternocleidomastoid. The anterior cervical space often provides a symmetric landmark on transverse imaging.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 15 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which of the following is false about the given histology? It consists of the hepatic artery, hepatic vein, and bile duct It makes the center of the portal lobule Both blood and bile flow the following structure to the center Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,3", "correct": true}, {"label": "B", "text": "2,3", "correct": false}, {"label": "C", "text": "2", "correct": false}, {"label": "D", "text": "1,2,3", "correct": false}], "correct_answer": "A. 1,3", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391720991-QTDA003001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,3 The following histology is of the liver showing a portal lobule and the structure labeled Portal Triad which could be identified by the presence of a triangular structure having a portal vein, hepatic artery, and bile duct connected to the central vein by lines of hepatocytes arranged in a row. The Portal lobule is a structure that comprises three central veins in the periphery and a portal triad in the Portal Triad comprises the portal vein, hepatic artery, and bile duct. It doesn’t include the hepatic vein. The blood flows from the hepatic artery and portal vein towards the central vein, but the direction of the bile flow is opposite to the blood flow as the bile flows from the bile canaliculi towards the bile duct.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-Year-old male was brought to the emergency department after complaining of sudden periumbilical pain, which transferred to the right lower quadrant of the anterior abdominal wall after time. The patient was taken into surgery, a part of the mesentery was cut, and a blood vessel was ligated to stop bleeding. What might be the origin of the ligated artery?", "options": [{"label": "A", "text": "Inferior Mesenteric Artery", "correct": false}, {"label": "B", "text": "Right Colic artery", "correct": false}, {"label": "C", "text": "Ileocolic artery", "correct": true}, {"label": "D", "text": "Sigmoid artery", "correct": false}], "correct_answer": "C. Ileocolic artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ileocolic artery This is caused due to involvement of the parietal peritoneum. The artery supplying the appendix is the appendicular artery originating from the ileocolic artery, a branch of the superior mesenteric artery. The patient came with a classical presentation of acute appendicitis, which is the inflammation of the The periumbilical pain was a referred pain because segment T10 of the spinal cord innervates both appendix and the umbilicus; with increasing inflammation, pain is felt in the right iliac fossa.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 50-year-old male is brought to the emergency department by ambulance after a traumatic accident. He complained of abdominal and pelvic pain. Genitourinary examination shows severe ecchymosis in the perineum and fresh blood in the urethral meatus. Radiography reveals multiple fractures of the pelvis. A retrograde urethrogram is performed, and dye leakage indicates a urethral tear at the point of the membranous urethra. Into which of the following spaces is the dye most likely leaking?", "options": [{"label": "A", "text": "Superficial Perineal Space", "correct": false}, {"label": "B", "text": "Extra peritoneal space", "correct": true}, {"label": "C", "text": "Rectovesical Space", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "B. Extra peritoneal space", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Extra peritoneal space The tear is in the membranous urethra which is a type of deep extravasation and in deep extravasation the urine or the dye will spreads upward into the extra peritoneal space of the pelvis around bladder and prostate into the anterior abdominal wall due to strong attachment of urogenital diaphragm to the ischiopubic rami of the pelvis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The urine would have accumulated in superficial perineal pouch if the tear would have been in the spongy part of the urethra. Option: C. The rectovesical space is the portion of the peritoneal cavity that is between the rectum and bladder. It is the lowest part of the peritoneal cavity. The rupture of urethra which is an extra peritoneal structure would not result in leakage of urine in peritoneal cavity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 70 year old male patient presents to emergency with a 1-day history of intermittent epigastric abdominal pain that radiates into his back. The patient reports that the pain has been increasing in severity over the past few hours; he vomited after lunch, which led him to seek medical help. The patient has a history of hypertension that is being controlled with metoprolol. He has not experienced fever, diarrhea, or other symptoms associated with his abdominal pain. His vital signs are BP 91/60 mmHg; pulse rate (87 bpm) and he has no fever. On physical examination, the patient's abdomen is tender in the epigastric area with guarding but without mass or rebound. The ultrasound confirmed Abdominal Aortic Aneurysm. It also identified intestinal blockage at the level of duodenum due to the dilation. Which part of the duodenum is most vulnerable to obstruction based on the case?", "options": [{"label": "A", "text": "1st Part", "correct": false}, {"label": "B", "text": "2nd part", "correct": false}, {"label": "C", "text": "3rd part", "correct": true}, {"label": "D", "text": "4th part", "correct": false}], "correct_answer": "C. 3rd part", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>3rd part The third part of duodenum lies between the Superior Mesenteric artery and Abdominal Aorta. It acts like a nut between these tongs formed by the artery. So it is most vulnerable to obstruction after abdominal aortic dilation or aneurysm- known as Wilkie’s syndrome.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 16 year old boy is brought to a clinician with complaints of severe lower abdominal pain followed by vomiting blood. There was no alteration in bowel habits and the pain did not radiate anywhere else. O/E- Patient was tachycardic and had shortness of breath. Radiological examination did not reveal much gas clouds under the diaphragm. After further examination, the clinician diagnosed the boy to be suffering from Posterior Duodenal Ulcer. Which structure is majorly damaged in this clinical condition?", "options": [{"label": "A", "text": "Peritoneum around the proximal duodenum", "correct": false}, {"label": "B", "text": "Inferior Pancreatico-duodenal artery", "correct": false}, {"label": "C", "text": "Superior Pancreatico-duodenal artery", "correct": true}, {"label": "D", "text": "Right Gastroepiploic artery", "correct": false}], "correct_answer": "C. Superior Pancreatico-duodenal artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior Pancreatico-duodenal artery Posterior superior pancreatico-duodenal artery (branch of Gastroduodenal Artery) supplies the anterior and posterior part of the 1st part of duodenum, where the ulceration is present.</p>\n<p><strong>Highyeild:</strong></p><p>Duodenal ulcers located on the posterior wall are more common than those found on the anterior wall. Posterior ulcers are more likely to erode through intestinal wall into branches of the Gastroduodenal artery, resulting in massive bleeding. Ulcers located on the anterior side of the duodenal wall are more likely to perforate, and therefore, present with free air and peritonitis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Peritoneal covering is present anteriorly to the duodenum and there are not much gas clouds in the sub-diaphragmatic part. This indicates that there is no damage to the peritoneum around the proximal duodenum. Option: B. This option is wrong as the Inferior pancreatico-duodenal artery is a branch of the Superior Mesenteric artery and not the Inferior Mesenteric Artery. Also, the inferior pancreaticoduodenal artery supplies the part after the 2nd part of the duodenum. Ulceration does not take place over here. Option: D. Right Gastroepiploic artery is related to the blood supply along the greater curvature of the stomach. Thus it cannot be injured in the case of Posterior Duodenal Ulcer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 40 year old man visits the Gastroenterology OPD with symptoms of bloating in the abdomen, nausea, vomiting (bile), weight loss, small bowel obstruction. After examination, the clinician diagnoses the condition to be Willkie's Syndrome. This is caused due to obstruction of the inferior part of the duodenum by an artery which crosses it anteriorly. What is the name of this artery and what is the level of its origin from the Abdominal Aorta?", "options": [{"label": "A", "text": "Celiac Trunk. T 12", "correct": false}, {"label": "B", "text": "Right renal artery , L 1-2", "correct": false}, {"label": "C", "text": "Superior Mesenteric Artery , L 1", "correct": true}, {"label": "D", "text": "Inferior Mesenteric Artery, L 3", "correct": false}], "correct_answer": "C. Superior Mesenteric Artery , L 1", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior Mesenteric Artery , L 1 Crosses the 3rd part/ inferior part of the duodenum anteriorly when it crosses to the opposite side of the midline. Any obstruction in this artery gives rise to the Superior Mesenteric Artery Syndrome/Wilkie’s Syndrome which causes compression of the duodenum and gives rise to the listed symptoms.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Celiac Trunk cannot cross the 3rd part of the duodenum as it is responsible for the supply of foregut structures and the 3rd part/ inferior part of the duodenum is a midgut derived structure. Moreover, the Celiac trunk is NOT related to the inferior duodenum. Option: B. Right renal artery arise from the abdominal aorta at the L1-2 vertebral body level, inferior to the origin of the superior mesenteric artery. Anteriorly, the proximal portion of the right renal artery is related to inferior vena cava, while the distal portion is related to the shorter right renal vein. These structures separate it from the second part of the duodenum and head of the pancreas. Option: D. Inferior mesenteric artery does not cross the duodenum at any point. The inferior part of the duodenum is located at L3 level and the inferior mesenteric artery is derived from L3 level posteriorly and slightly inferiorly to it. Thus is does not cross the duodenum at any time and the option is wrong.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During the surgical repair of a perforated duodenal ulcer in a 47-year-old male patient, the gastroduodenal artery is ligated. A branch of which of the following arteries will continue to supply blood to the pancreas in this patient?", "options": [{"label": "A", "text": "Inferior Mesenteric", "correct": false}, {"label": "B", "text": "Left gastric", "correct": false}, {"label": "C", "text": "Right gastric", "correct": false}, {"label": "D", "text": "Superior mesenteric", "correct": true}], "correct_answer": "D. Superior mesenteric", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior mesenteric The superior mesenteric artery will supply the pancreas if the gastroduodenal artery is ligated. It arises immediately inferior to the celiac trunk from the thoracic aorta. Its first branches are the anterior and posterior inferior pancreaticoduodenal arteries, which anastomose with the superior pancreaticoduodenal arteries (which take origin from the gastroduodenal branch of the celiac trunk) in supplying the pancreas with oxygenated blood.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The inferior mesenteric artery is the most inferior of the three main arterial branches supplying the gastrointestinal tract. It supplies the hindgut from the left colic flexure to the rectum. Option: B. The left gastric artery is the smallest branch of the celiac trunk and supplies the cardioesophageal junction, the inferior esophagus, and the lesser curvature of the stomach. Option: C. The right gastric artery arises from the common hepatic artery, which is a branch from the celiac trunk. It supplies the lesser curvature of the stomach and anastomoses with the left gastric artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 70-year-old man is admitted to the emergency department with severe diarrhea. An arteriogram reveals 90% blockage at the origin of the inferior mesenteric artery from the aorta. Which of the following arteries would most likely provide collateral supply to the descending colon?", "options": [{"label": "A", "text": "Left gastroepiploic artery", "correct": false}, {"label": "B", "text": "Middle colic artery", "correct": true}, {"label": "C", "text": "Sigmoid artery", "correct": false}, {"label": "D", "text": "Splenic artery", "correct": false}], "correct_answer": "B. Middle colic artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Middle colic artery The middle colic artery can provide collateral supply to the descending colon when the inferior mesenteric artery is blocked or ligated. It is one of the first branches of the superior mesenteric artery and supplies the transverse colon . It provides collateral blood supply both to the ascending colon and descending colon by anastomosing with the right colic branch of the superior mesenteric artery and with the left colic artery, a branch from the inferior mesenteric artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The left gastroepiploic artery, also known as the left gastro-omental artery, is a branch of the splenic artery and supplies the greater curvature of the stomach along with the right gastro-omental branch of the gastroduodenal artery. Option: C. The sigmoid arteries are branches from the inferior mesenteric artery and supply the inferior portion of the descending colon, the sigmoid colon, and the rectum. The sigmoid arteries have no contributing branches to the foregut or midgut. Option: D. The splenic artery is the largest artery arising from the celiac trunk. It supplies the spleen and the neck, body, and tail of the pancreas and also provides short gastric branches to the stomach. It supplies no structures in the midgut or hindgut.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 61-year-old woman had been scheduled for a cholecystectomy. During the operation the scissors of the surgical resident accidentally entered the tissues immediately posterior to the epiploic (omental) foramen (its posterior boundary). The surgical field was filled immediately by profuse bleeding. Which of the following vessels was the most likely source of bleeding?", "options": [{"label": "A", "text": "Aorta", "correct": false}, {"label": "B", "text": "Inferior vena cava", "correct": true}, {"label": "C", "text": "Portal vein", "correct": false}, {"label": "D", "text": "Right renal artery", "correct": false}], "correct_answer": "B. Inferior vena cava", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior vena cava The epiploic foramen (of Winslow) is the only natural opening between the lesser and greater sacs of the peritoneal cavity . It is bounded superiorly by the visceral peritoneum (liver capsule of Glisson) on the caudate lobe of the liver, inferiorly by the peritoneum on the first part of the duodenum, anteriorly by the free edge of the hepatoduodenal ligament, and posteriorly by the parietal peritoneum covering the inferior vena cava. Therefore, the inferior vena cava would be the most likely source of bleeding.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The aorta lies to the left of the inferior vena cava in the abdomen. Option: C & D. The portal vein, right renal artery, and superior mesenteric vein are not borders of the epiploic foramen.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 48-year-old man has had three episodes of upper gastrointestinal bleeding from esophageal varices. He has a history of chronic alcoholism but has recently been rehabilitated. The further evaluation shows ascites and splenomegaly. Which surgical venous anastomoses are most commonly used to relieve these symptoms and signs before a liver transplant is attempted?", "options": [{"label": "A", "text": "Left gastric to splenic vein", "correct": false}, {"label": "B", "text": "Right gastric to left gastric vein", "correct": false}, {"label": "C", "text": "Right renal to right gonadal vein", "correct": false}, {"label": "D", "text": "Splenic to left renal vein", "correct": true}], "correct_answer": "D. Splenic to left renal vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Splenic to left renal vein Surgical anastomoses to alleviate symptoms of portal hypertension are rooted in the premise that the connection of a large portal vein to a large systemic vein allows for collateral drainage of the portal system. The splenic vein, a major tributary component of the portal venous system, and the left renal vein, a part of the canal-systemic venous system, ideally allow for a low-resistance, easily performed anastomosis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options: A, B, C. Anastomosing the left gastric vein to the splenic vein, the right gastric vein to the left gastric vein, or the superior mesenteric vein to the inferior mesenteric vein would all be ineffectual because each of these veins is a component of just the portal venous system. In addition, the right renal and right gonadal veins are tributaries of the canal system, and surgical connection would not benefit.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 42-year-old man is admitted to the hospital with severe hematemesis. Radiographic studies reveal hepatomegaly and esophageal varices. During physical examinatioDA003010n, it is observed that the patient is icteric (jaundiced), and dilated veins (\"caput medusae\") are seen on his anterior abdominal wall. Which of the following venous structures is most likely obstructed for the development of caput medusae?", "options": [{"label": "A", "text": "Portal Vein", "correct": true}, {"label": "B", "text": "Inferior vena cava", "correct": false}, {"label": "C", "text": "Superior vena cava", "correct": false}, {"label": "D", "text": "Lateral thoracic vein", "correct": false}], "correct_answer": "A. Portal Vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Portal Vein Caput medusae (referring to the head of Medusa, whose hair was formed by snakes) is caused by severely elevated portal pressure, with venous reflux from the liver to the periumbilical veins, by way of the usually collapsed veins in the ligamentum teres. The presence of caput medusae is generally associated with end-stage disease. Caput medusae are identified by the appearance of engorged veins radiating toward the lower limbs. The portal vein is the central connection of these anastomoses.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options: B, C & D. Obstruction of the inferior vena cava, superior vena cava, and lateral thoracic vein do not cause portal hypertension and would not produce these symptoms.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "From which of the following structure Arch of the aorta is derived?", "options": [{"label": "A", "text": "2nd Aortic Arch", "correct": false}, {"label": "B", "text": "3rd aortic arch", "correct": false}, {"label": "C", "text": "3rd pharyngeal arch", "correct": false}, {"label": "D", "text": "4th pharyngeal arch", "correct": true}], "correct_answer": "D. 4th pharyngeal arch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4th pharyngeal arch Arch number Arch name Embryonic cartilage Cartilage derivative Muscle Nerve Artery 1 Mandibular Quadrate Meckel's Incus Malleus Anterior ligament of malleus Spine of sphenoid Sphenomandibular ligament Genial tubercle of mandible Tensor tympani Muscles of mastication Mylohyoid Anterior belly of digastric Tensor veli palatine Trigeminal (V) Mandibular division First aortic arch artery (transitory) 2 Hyoid Reichert's • Stapes • Styloid process of temporal bone • Styloid process of temporal bone • Stylohyoid ligament • Lesser horn and upper part of body of hyoid bone • Stapedius • Stylohyoid Muscle • Facial muscles, include ■ Buccinator ■ Platysma ■ Posterior belly digastric Facial (VII) Stapedial artery (transitory) 3 Third Greater horn and lower part of body of hyoid bone Stylopharyngeus Glossopharyngeal (IX) Common carotid artery 4 Fourth Thyroid cartilageCorniculate cartilage Cuneiform cartilage Pharyngeal and extrinsic laryngeal muscles, levator veli palatini Vagus (X) Pharyngeal branch • Proximal part of subclavian artery on the right • Arch of aorta between origins of left common carotid and left subclavian arteries 5 Sixth Arytenoid cartilages Intrinsic laryngeal muscles Vagus (X) Recurrent laryngeal branch Part between the pulmonary trunk and dorsal aorta becomes ductus arteriosus on left, disappears on right</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 50y old male complained of fever, malaise, and throbbing pain in the perianal region. His vitals were normal on examination, and it was diagnosed as an ischiorectal abscess. The patient was taken to the operation theater for incision and drainage. During the incision and drainage of the ischiorectal abscess, which nerve is injured?", "options": [{"label": "A", "text": "Superior Rectal Nerve", "correct": false}, {"label": "B", "text": "Inferior rectal nerve", "correct": false}, {"label": "C", "text": "Superior gluteal nerve", "correct": false}, {"label": "D", "text": "Inferior gluteal nerve", "correct": true}], "correct_answer": "D. Inferior gluteal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior gluteal nerve Contents of Ischioanal Fossa Ischioanal pad of fat. Inferior rectal nerve and vessels. They pass through the fossa from the lateral to the medial side. They arch upwards above the fat to supply mucous membrane, external sphincter, and the skin around the anus. Pudendal canal with its contents. This canal lies along the lateral wall of the fossa. Posterior scrotal or posterior labial (in females) nerves and vessels. They cross the anterolateral part of the fossa and enter the urogenital triangle. Perineal branch of the fourth sacral (S4) nerve. It enters the posterior angle of the fossa and runs over the levator ani to the external anal sphincter. They are perforating cutaneous branches of nerves S2, S3. They appear at the lower border of the gluteus maximus, in the posterior part of the fossa.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 37-year-old man presented with acute penile pain, penile swelling, and the inability to pass urine after blunt trauma. In this patient with penile injury, Colle's fascia prevents extravasation of urine in:", "options": [{"label": "A", "text": "Ischiorectal Fossa", "correct": true}, {"label": "B", "text": "Abdomen", "correct": false}, {"label": "C", "text": "Perineum", "correct": false}, {"label": "D", "text": "None", "correct": false}], "correct_answer": "A. Ischiorectal Fossa", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ischiorectal Fossa Colle's fascia prevents the passage of extravasated urine due to rupture of urethra backwards into ischiorectal fossa. Colles' fascia is attached posteriorly to the posterior border of perineal membrane, and on each side to pubic arch below the crus penis. Anteriorly, it is continuous with the fascia of the scrotum containing the dartos, fascia of the penis, and with the membranous layer of the superficial fascia of the anterior abdominal wall or fascia of Scarpa.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 24 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which among the following bones takes part in the formation of medial longitudinal arch? A. Calcaneum B. Cuboid C. Talus D.Medial cuneiform Choose the correct answer from the below options:", "options": [{"label": "A", "text": "b, a, and d", "correct": false}, {"label": "B", "text": "c, b, and d", "correct": false}, {"label": "C", "text": "a, c, and d", "correct": true}, {"label": "D", "text": "All of above", "correct": false}], "correct_answer": "C. a, c, and d", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>a, c, and d Medial longitudinal arch is formed by the following bones: It is made up of the calcaneus, talar head, navicular, the three cuneiforms, and the medial three metatarsals. Medial longitudinal arch Medial Longitudinal Arch: This arch is considerably higher, more mobile, and more resilient than the lateral. It is considered as a big arc of a small circle. Its constitution is as follows: Ends : The anterior end is formed by the heads of the first, second, and third metatarsals. The phalanges do not take part in forming the arches. The posterior end of this arch is formed by the medial tubercle of the calcaneum. Summit The summit of the arch is formed by the superior articular surface of the body of the talus. Pillars The anterior pillar is long and weak. It is formed by the talus, the navicular, the three cuneiform bones, and the first three metatarsal bones . The posterior pillar is short and strong. It is formed by the medial part of the calcaneum. The main joint of the arch is the talocalcaneonavicular joint.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. b, a, and d Option: B . c, b, and d Option: D. All of above Option A, B, and D are incorrect because Cuboid bone contributes to the formation of the lateral longitudinal arch. Lateral longitudinal arch The lateral longitudinal arch is a much less pronounced arch than the medial one. The bones making up the lateral longitudinal arch are the calcaneus, the cuboid, and the fourth and fifth metatarsals; they contribute little to the arch in terms of stability.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following does not take part in the formation of the lateral longitudinal arch?", "options": [{"label": "A", "text": "Calcaneum", "correct": false}, {"label": "B", "text": "Cuboid", "correct": false}, {"label": "C", "text": "Navicular", "correct": true}, {"label": "D", "text": "4th metatarsal", "correct": false}], "correct_answer": "C. Navicular", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Navicular The navicular bone is part of the medial longitudinal arch. The bones making up the lateral longitudinal arch are the calcaneus, the cuboid, and the fourth and fifth metatarsals; they contribute little to the arch in terms of stability.</p>\n<p><strong>Highyeild:</strong></p><p>lateral longitudinal arch The medial longitudinal arch is formed by the following bones: It is made up of the calcaneus, talar head, navicular, the three cuneiforms, and the medial three metatarsals. Options A, B & D takes part in the formation of the lateral longitudinal arch #EXTRA EDGE : Lateral Longitudinal Arch: This arch is characteristically low, has limited mobility and is built to transmit weight and thrust to the ground. It is considered as a small arc of a big circle. This is in contrast to the medial longitudinal arch which acts as a shock absorber. The constitution of the lateral longitudinal arch is as follows. Ends The anterior end of the arch is formed by the heads of the 4th and 5th metatarsal bones. The posterior end is formed by the lateral tubercle of the calcaneum. Summit The summit lies at the level of the articular facets on the superior surface of the calcaneum at the level of the subtalar joint. Pillars The anterior pillar is long and weak. It is formed by the cuboid bone and by the 4th and 5th metatarsals. The posterior pillar is short and strong. It is formed by the lateral half of the calcaneum. The main joint of the arch is the calcaneocuboid joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following is/are true statements regarding the maintenance of arches of the foot except:", "options": [{"label": "A", "text": "The shape of the bones concerned.", "correct": false}, {"label": "B", "text": "Intersegmental ties/staples or ligaments (and muscles)", "correct": false}, {"label": "C", "text": "Tie beams or bow strings that connect the two ends of the arch.", "correct": false}, {"label": "D", "text": "All are true statements", "correct": true}], "correct_answer": "D. All are true statements", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All are true statements Option: A. Shape of the bones concerned. Bony Factor : The posterior transverse arch is formed, and maintained mainly because of the fact that many of the tarsal bones involved (e.g., the cuneiform bones), and the heads of the metatarsal bones, are wedge-shaped, the apex of the wedge pointing downwards. Option: B. Intersegmental ties/staples or ligaments (and muscles) Intersegmental Ties : All arches are supported by the ligaments uniting the bones concerned. The most important of these are as follows: The spring ligament for the medial longitudinal arch. The long and short plantar ligaments for the lateral longitudinal arch. In the case of the transverse arch , the metatarsal bones are held together by the interosseous muscles also. Option: C. Tie beams or bow strings that connect the two ends of the arch. Tie Beams : The longitudinal arches are prevented from flattening by the plantar aponeurosis, and by the muscles of the first layer of the sole. These structures keep the anterior and posterior ends of these arches pulled together. In the case of the transverse arch, the adductor hallucis acts as a tie beam. Slings: The summit of the medial longitudinal arch is pulled upwards by tendons passing from the posterior compartment of the leg into the sole, i.e., tibialis posterior, flexor hallucis longus, flexor digitorum longus. The summit of the lateral longitudinal arch is pulled upwards by the peroneus longus and peroneus brevis. The tendons of tibialis anterior and peroneus longus together form a sling (stirrup) which keeps the middle of the foot pulled upwards, thus supporting the longitudinal arches. As the tendon of the peroneus longus runs transversely across the sole , it pulls the medial and lateral margins of the sole closer together, thus maintaining the transverse arches. The transverse arch is also supported by tibialis posterior which grips many of the bones of the sole through its slips.</p>\n<p><strong>Extraedge:</strong></p><p>' Suspension: Medial longitudinal arch- Tibialis anterior Lateral longitudinal arch - Peroneus longus. Therefore all options are correct, so option D. All true statements are correct answers.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following is/ are major muscular support of the lateral longitudinal arch? A. Peroneus longus B. Peroneus tertius C. Peroneus brevis D. Extensor digitorum brevis Select the correct statement from the given below code:", "options": [{"label": "A", "text": "d, b and c", "correct": false}, {"label": "B", "text": "c, a and d", "correct": false}, {"label": "C", "text": "a, b and c", "correct": true}, {"label": "D", "text": "All of above", "correct": false}], "correct_answer": "C. a, b and c", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>a, b and c The lateral longitudinal arch is formed by the calcaneum, cuboid, 4th and 5th metatarsals . It is rather shallow and gets flattened on weight bearing.</p>\n<p><strong>Highyeild:</strong></p><p>Lateral longitudinal Arch support ' This arch is supported by a long plantar ligament, a short plantar ligament . Plantar aponeurosis acts as a tie beam. Flexor digitorum brevis, flexor digiti minimi, and abductor digiti minimi act as tie beams. Peroneus longus, peroneus brevis and peroneus tertius support this arch. Therefore Option C is the correct answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following below statements is/are true regarding the functions of the arches of the foot? The arches of the foot distribute body weight to the weight-bearing areas of the sole, mainly the heel and the toes. The arches act as springs They also act as shock absorbers The concavity of the arches protects the soft tissues of the sole against pressure. Select the correct statement from the given below code:", "options": [{"label": "A", "text": "1, and 2 are true", "correct": false}, {"label": "B", "text": "Only 1 true", "correct": false}, {"label": "C", "text": "3, and 4 are true", "correct": false}, {"label": "D", "text": "All are true", "correct": true}], "correct_answer": "D. All are true", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All are true Option: A. FUNCTIONS OF ARCHES The arches of the foot distribute body weight to the weight-bearing areas of the sole, mainly the heel and the toes. Out of the latter, the weight is borne mainly on the first and fifth toes. The lateral border of the foot bears some weight, but this is reduced due to the presence of the lateral longitudinal arch. The arches act as springs (chiefly the medial longitudinal arch) which are of great help in walking and running. Option: B. Arches of the foot also act as shock absorbers in stepping and particularly in jumping. Option: C. The concavity of the arches protects the soft tissues of the sole against pressure. The character of the medial longitudinal arch is resiliency and that of the lateral longitudinal arch is rigidit Therefore Option D: All are correct is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Lateral longitudinal Arch support</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 22-year-old male adult was not qualified in his medical examination for police recruitment, due to a flat foot. What are the effects of flat-foot that are responsible for his disqualification?", "options": [{"label": "A", "text": "Loss of spring in the foot leads to a clumsy, shuffling gait.", "correct": false}, {"label": "B", "text": "Loss of shock-absorbing function makes the foot more liable to trauma and osteoarthritis.", "correct": false}, {"label": "C", "text": "Loss of the concavity of the sole leads to compression of the nerves and vessels of the sole.", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above When the feet do not show upward concavity along the medial border of the foot, the foot is called a \"flat foot\". If such a person puts his wet feet on the ground, there will be an impression of the whole foot. Flat-foot persons cannot run as fast as arched-foot The police persons are required to run fast, so a flat-foot person may be disqualified. Flat Foot Absence or collapse of the arches leads to flat-foot (pes planus), which may be congenital or acquired. The effects of a flat foot are as follows. Option: A. Loss of spring in the foot leads to a clumsy, shuffling gait. Option: B. Loss of shock-absorbing function makes the foot more liable to trauma and osteoarthritis. Option: C. Loss of the concavity of the sole leads to compression of the nerves and vessels of the sole. Compression of the communication between the lateral and medial plantar nerves causes neuralgic pain in the forefoot (metatarsalgia). Compression of blood vessels may cause vascular disturbances in the toes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 50-year-old patient was brought to emergency with a complaint of chest pain for the last 20 mins which is severe and is not relieved by any means. Patient HE-110b/m spo2-98./, BP-140/90 mmhg. he does not have a relevant history. ECG Was taken to show ST elevation. Angiography done. Which shows occlusion of the right coronary artery among the following from which RCA originates?", "options": [{"label": "A", "text": "Aortic Arch", "correct": false}, {"label": "B", "text": "Anterior aortic sinus", "correct": true}, {"label": "C", "text": "Right Posterior aortic sinus", "correct": false}, {"label": "D", "text": "Left posterior aortic sinus", "correct": false}], "correct_answer": "B. Anterior aortic sinus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior aortic sinus Anterior aortic sinus -The right coronary artery arises from the anterior (‘right coronary’) aortic sinus; its ostium is usually below the sinotubular junction. The artery is usually single but as many as four right ostia have been observed, reflecting the independent origins of the conal, sino-atrial node, and ventricular arteries.</p>\n<p><strong>Highyeild:</strong></p><p>There are two primary coronary arteries, the right coronary artery (RCA) and the left main coronary artery (LMCA). Both of these originate from the root of the aorta. The RCA emerges from the anterior ascending aorta and supplies blood primarily to the right atrium, and right ventricle. The left coronary artery arises from the aorta within the left cusp of the aortic valve and feeds blood to the left side of the heart. Origin of Coronary arteries</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A - Aortic arch -Three branches arise from the convex aspect of the arch: the brachiocephalic trunk left common carotid and left subclavian arteries. They may branch from the beginning of the arch or the superior part of the ascending aorta. The distance between these origins varies, the most frequent being approximation of the left common carotid artery to the brachiocephalic trunk. Other branches may arise from the aortic arch, including the inferior thyroid, thyroidea ima, thymic, left coronary and bronchial arteries. Option C - The left coronary artery arises from the left posterior (left coronary) aortic sinus; the ostium sometimes lies inferior to the margin of the leaflets and maybe double, leading into major initial branches, usually the circumflex and anterior interventricular (descending) arteries. Option D -left posterior aortic sinus does not give origin to any coronary artery so-called noncoronary aortic sinus</p>\n<p><strong>Extraedge:</strong></p><p>Coronary artery dominance is described as the coronary artery that gives branches to supply the right posterior descending artery and supplies the inferior wall of the heart. In 80 to 85% of the population, the right coronary artery supplies the posterior descending artery, making it right heart dominant while in 7 to 13% of the population, the left coronary artery supplies the posterior descending artery, making it left heart dominant. In 7 to 8% of the population, both right and left coronary arteries supply the posterior descending artery, making it right and left codominance. Narrowing of coronary arteries is more frequent in those who are left dominant when compared to those who have right dominant or codominant hearts.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient treated for a case of MI. You were asked to present the case of MI. In the case presentation, you presented an echo finding which revealed complete obstruction of RCA. Your professor asked which branch of RCA supplies the infundibulum part of the ventricle and what its other name?", "options": [{"label": "A", "text": "Acute Artery", "correct": false}, {"label": "B", "text": "Obtuse artery", "correct": false}, {"label": "C", "text": "Third coronary artery", "correct": true}, {"label": "D", "text": "Annulus of vieussens", "correct": false}], "correct_answer": "C. Third coronary artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Third coronary artery The first branch of RCA is the right Conal artery, This vessel arises independently from the anterior aortic sinus in approximately one-third of hearts and is therefore sometimes termed the ‘third coronary artery. Conal branch of the right coronary artery branches anteroinferiorly over the conus arteriosus (infundibulum) and over the superior aspect of the right ventricle, sometimes anastomosing with a similar branch from the anterior interventricular (left anterior descending) artery to form Vieussens arterial ring, an inconstant anastomosis around the right ventricular outflow tract that may provide an important collateral circulation in cases of arterial occlusion.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Acute artery - from RCA a branch run along the inferior border of the heart which is called the Right marginal artery which is also called the acute artery Option B. Obtuse artery- a branch of LCA runs along the left border of the heart and supplies It is called the left marginal artery Option D. Annulus of Vieussens- Vieussens' arterial ring is a rare anatomic variant consisting of an anastomotic connection between the conus artery and branch vessels of the left coronary artery.</p>\n<p><strong>Extraedge:</strong></p><p>Vieussens artery arises from the conus artery, a branch of the right coronary artery, and connects to the proximal right ventricular branch . In this way, it forms a connection between the left and right main coronary arteries. It is a rare variant with an estimated prevalence of approximately 3%. Vieussens' arterial ring may serve as a protective factor in coronary artery disease by providing a pathway for collateral circulation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You are working as a junior resident in the forensic department in one post-mortem case you examined the heart. In that case, you searched for dominance of the heart. You noticed that this is a case of the right dominance of the heart. Which branch of the artery leads to right cardiac dominance?", "options": [{"label": "A", "text": "Circumflex Artery", "correct": false}, {"label": "B", "text": "RCA", "correct": true}, {"label": "C", "text": "Both A and B", "correct": false}, {"label": "D", "text": "Right marginal artery", "correct": false}], "correct_answer": "B. RCA", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>RCA Coronary artery dominance is described as the coronary artery that gives branches to supply the right posterior descending artery and supplies the inferior wall of the heart. The posterior interventricular artery is typically a branch of the right coronary artery (70%, known as right dominance). Alternatively, the PIV can be a branch of the circumflex coronary artery (10%, known as left dominance) which itself is a branch of the left coronary artery. It can also be supplied by an anastomosis of the left and right coronary arteries (20%, known as codominance).</p>\n<p><strong>Highyeild:</strong></p><p>The posterior interventricular artery is typically a branch of the right coronary artery (70%, known as right dominance). Alternatively, the PIV can be a branch of the circumflex coronary artery (10%, known as left dominance) which itself is a branch of the left coronary artery. It can also be supplied by an anastomosis of the left and right coronary arteries (20%, known as codominance). The posterior interventricular artery ( PIV/PIVA ) most often called the posterior descending artery ( PDA ), is an artery running in the posterior interventricular sulcus to the apex of the heart where it meets with the anterior interventricular artery or also known as the Left Anterior Descending artery. The PIV artery supplies the posterior third of the interventricular septum . The remaining anterior two-thirds is supplied by the anterior interventricular artery which is a septal branch of the left anterior descending artery, which is a branch of the left coronary artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Posterior interventricular artery can be a branch of the circumflex coronary artery (10%, known as left dominance) which itself is a branch of the left coronary artery. Option C. When both RCA and circumflex arteries jointly give a branch to PIVA then it is called Codominance. Option D. Right marginal artery - from RCA a branch runs along the inferior border called the right marginal or acute Artery.</p>\n<p><strong>Extraedge:</strong></p><p>The term \"dominance\" of either side of the coronary arterial circulation is determined by which artery gives rise to the PDA and supplies the diaphragmatic surface of the heart. The right coronary is dominant in approximately 65% to 70% of the population. It's important to keep in mind that the term \"dominant\" is potentially misleading since it can be interpreted as the vessel which irrigates the greater portion of the myocardium . However, it is always the left coronary artery that supplies the greater myocardial portion.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were busy dealing with RTA in an emergency suddenly an adult came with a complaint of sudden onset of chest pain which occurs after eating food from outside as stated by the patient. On examination HR-120 beats per minute Spo2-99% BP-160/90 mmHg. ECG was taken which revealed ST Elevation involving LCA. What is the origin of LCA?", "options": [{"label": "A", "text": "Aortic Arch", "correct": false}, {"label": "B", "text": "Anterior aortic sinus", "correct": false}, {"label": "C", "text": "Right Posterior aortic sinus", "correct": false}, {"label": "D", "text": "Left posterior aortic sinus", "correct": true}], "correct_answer": "D. Left posterior aortic sinus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left posterior aortic sinus The left aortic or left posterior aortic sinus gives rise to the left coronary artery . The right aortic or anterior aortic sinus gives rise to the right coronary artery. The posterior aortic or right posterior aortic sinus usually gives rise to no vessels. It is often known as the non-coronary sinus .</p>\n<p><strong>Highyeild:</strong></p><p>The left coronary artery arises from the left posterior (left coronary) aortic sinus; the ostium sometimes lies inferior to the margin of the leaflets and maybe double, leading into major initial branches, usually the circumflex and anterior interventricular (descending) arteries.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Aortic arch -Three branches arise from the convex aspect of the arch: the brachiocephalic trunk left common carotid, and left subclavian arteries. They may branch from the beginning of the arch or the superior part of the ascending aorta. The distance between these origins varies, the most frequent being approximation of the left common carotid artery to the brachiocephalic trunk. Other branches may arise from the aortic arch, including the inferior thyroid, thyroidea ima, thymic, left coronary and bronchial arteries. Option B. Anterior aortic sinus-The right coronary artery arises from the anterior ('right coronary') aortic sinus; its ostium is usually below the sinutubular junction. The artery is usually single but as many as four right ostia have been observed, reflecting the independent origins of the conal, sinoatrial node, and ventricular arteries</p>\n<p><strong>Extraedge:</strong></p><p>An aortic sinus, also called the sinuses of Valsalva is one of the anatomic dilatations of the ascending aorta, which occurs just above the aortic valve. These widenings are between the wall of the aorta and each of the three cusps of the aortic valve. There are generally three aortic sinuses: one anterior and 2 posterior sinuses. Cusps of the Aortic valve</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following is not a branch of RCA?", "options": [{"label": "A", "text": "Nodal Branch", "correct": false}, {"label": "B", "text": "Interventricular artery", "correct": false}, {"label": "C", "text": "Obtuse artery", "correct": true}, {"label": "D", "text": "Marginal artery", "correct": false}], "correct_answer": "C. Obtuse artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Obtuse artery Obtuse artery- a branch of LCA run along the left border of the heart and supply them it is called the left marginal artery. The obtuse marginal artery (OMA) is one or two branches from the left circumflex branch(LCx) of the left main coronary artery (LMCA) . It supplies the most lateral wall of the left ventricle.</p>\n<p><strong>Highyeild:</strong></p><p>Branches of Right Coronary artery Anterior branches Conal branch Sinuatrial nodal branch Anterior atrial branches Anterior ventricular branches Marginal branches Right marginal (acute) artery Lateral atrial branches Inferior branches Atrioventricular branches Inferior (posterior) interventricular branch Interventricular septal branches Inferolateral branch</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Nodal Branch Option B. Interventricular artery Option D. Marginal artery Nodal, Interventricular, and Marginal all are branches of the right Coronary artery.</p>\n<p><strong>Extraedge:</strong></p><p>Branches of Coronary arteries</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Ram while reading about SAnode abnormality, remembered the anatomy viva time when he was asked about the blood supply of the SA node, Which of the following is the arterial supply of the SA node?", "options": [{"label": "A", "text": "Nodal Branch", "correct": true}, {"label": "B", "text": "Acute artery", "correct": false}, {"label": "C", "text": "Obtuse artery", "correct": false}, {"label": "D", "text": "Circumflex artery", "correct": false}], "correct_answer": "A. Nodal Branch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Nodal Branch The sinoatrial nodal artery (Sinoatrial artery) is an artery of the heart which supplies the sinoatrial node, the natural pacemaker center of the heart. It is usually a branch of the right coronary artery. It passes between the right atrium and the opening of the superior vena cava.</p>\n<p><strong>Highyeild:</strong></p><p>It arises from the right coronary artery in around 60% of individuals, from the left circumflex coronary artery in about 40% of individuals, and in less than 1% of humans, the artery has an anomalous origin directly from the coronary sinus, descending aorta, or distal right coronary artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B: ACUTE artery-from RCA a branch run along the inferior border of the heart which is called the Right marginal artery which is also called the acute artery Option C: obtuse artery- a branch of LCA run along the left border of the heart and supply them it is called the left marginal artery. Option D: circumflex artery- the branch of LCA circumflex artery, comparable to the anterior interventricular artery in caliber, curves left in the atrioventricular groove, and continues round the left cardiac border into the posterior part of the groove, terminating left of the crux in most hearts, although sometimes continuing as the posterior (inferior) interventricular artery. Proximally, the left atrial appendage usually overlaps it.</p>\n<p><strong>Extraedge:</strong></p><p>The origin of the sinoatrial node artery is not related to coronary artery dominance, which means the side (right or left) that provides circulation to the back of the heart. In contrast, the atrioventricular nodal branch, which is the artery that brings blood to the atrioventricular node, depends on coronary artery dominance.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Name the marked structure:", "options": [{"label": "A", "text": "Nodal Branch", "correct": false}, {"label": "B", "text": "Acute artery", "correct": false}, {"label": "C", "text": "Obtuse artery", "correct": false}, {"label": "D", "text": "Circumflex artery", "correct": true}], "correct_answer": "D. Circumflex artery", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/questionImage-1738568429028-EA03436.jpg"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Circumflex artery Circumflex artery- the branch of the Left Coronary Artery. Circumflex artery, comparable to the anterior interventricular artery in caliber, curves left in the atrioventricular groove, and continues round the left cardiac border into the posterior part of the groove, terminating left of the crux in most hearts, although sometimes continuing as the posterior (inferior) interventricular artery. Proximally, the left atrial appendage usually overlaps it.</p>\n<p><strong>Highyeild:</strong></p><p>The circumflex branch of the left coronary artery winds around the left side of the heart along the atrioventricular groove (coronary sulcus). It supplies the posterolateral portion of the left ventricle. In a minority of individuals, the left circumflex artery gives rise to the posterior interventricular artery, in which cases such a heart is deemed left dominant. Circumflex coronary artery</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Nodal branch - the branch of RCA 'Nodal' artery usually passes posteriorly in the groove between the right atrial appendage and aorta. It may originate from the circumflex branch of the left coronary artery. Whatever its origin, it usually branches around the base of the superior vena cava, typically as an arterial loop from which small branches supply the right atrium. A large branch, the ramus cristae terminalis, traverses the sinoatrial node; it would seem more appropriate to name this branch the 'nodal artery', Option B. ACUTE artery-from RCA a branch run along the inferior border of heart which is called the Right marginal artery which is also called the acute artery Option C. obtuse artery- a branch of LCA runs along the left border of heart and supply them it is called the left marginal artery.</p>\n<p><strong>Extraedge:</strong></p><p>The circumflex artery supplies the posterolateral left ventricle and the anterolateral papillary muscle. It also supplies the sinoatrial nodal artery in 38% of people. It supplies 15-25% of the left ventricle in the right-dominant systems. If the coronary anatomy is left-dominant, the circumflex artery supplies 40-50% of the left ventricle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A patient with syphilis develops an imbalance in walking with his eyes closed. He has to lift his foot and stamp on the ground to walk. Name the tract involved in a given condition.", "options": [{"label": "A", "text": "Spinocerebellar Tract", "correct": false}, {"label": "B", "text": "Dorsal column tract", "correct": true}, {"label": "C", "text": "Lateral spinothalamic tract", "correct": false}, {"label": "D", "text": "Vestibulospinal tract", "correct": false}], "correct_answer": "B. Dorsal column tract", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Dorsal column tract Given sign is Romberg’s sign Tabes dorsalis: Is a syphilitic degenerative lesion of the posterior white columns and posterior nerve roots. Is characterized by impairment of proprioceptive sensibility. The patient loses the sense of tactile discrimination, vibration, passive movement and appreciation of posture. The patient becomes ataxic, particularly if he closes his eyes because he loses his position sense for which he could, otherwise partially compensate by visual knowledge of his spatial relationship (Romberg's sign). Site of lesion in Tabes dorsalis Site of lesion in 'tabes dorsalis. Note the involvement of posterior white column and the posterior nerve roots at the point of their entrance into the spinal cord.</p>\n<p><strong>Highyeild:</strong></p><p>Poliomyelitis: I t is a viral disease which involves anterior horn cells leading to flaccid paralysis of the affected segments. It is a lower motor neuron paralysis. If poliomyelitis affects the upper cervical segments of the spinal cord, it may be fatal because of the involvement of the C4 segment which supplies the diaphragm through a phrenic nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Spinocerebellar Tract Option: C. Lateral spinothalamic tract Option: D. Vestibulospinal tract The given sign is Romberg’s sign and it is due to a lesion of the posterior white columns and posterior nerve roots, so Options A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The lumbar puncture in a child is done at a lower level-L4 vertebra as the spinal cord extends to the L3 vertebra. As it ascends to the level of the L1 vertebra in adults, lumbar puncture is done at the level of the L3 vertebra to prevent injury to the spinal cord.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The lesion in the right medial lemniscus leads to", "options": [{"label": "A", "text": "Loss of pain, crude touch, the temperature on the right side", "correct": false}, {"label": "B", "text": "Loss of temperature, pain, crude touch on the left side", "correct": false}, {"label": "C", "text": "Loss of stereognosis, proprioception, on the right side", "correct": false}, {"label": "D", "text": "Loss of stereognosis, proprioception, on the left side", "correct": true}], "correct_answer": "D. Loss of stereognosis, proprioception, on the left side", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Loss of stereognosis, proprioception, on the left side Fibres from the nucleus Gracilis and cuneatus cross and continue as medial lemniscus • So, lesion in medial lemniscus lead to contralateral loss of proprioception, stereognosis Pathway of (a) Posterior column; (b) Pain and temperature impulses</p>\n<p><strong>Highyeild:</strong></p><p>Proprioceptive Sensations The sensations like deep touch, pressure, tactile localisation (the ability to locate exactly the proprioceptive part touched), tactile discrimination (the ability to localize two separate points on the skin that is touched), stereognosis (ability to recognise the shape of an object held in hand) a sense of vibration are carried by fasciculus gracilis and fasciculus cuneatus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Loss of pain, crude touch, the temperature on the right side Option: B. Loss of temperature, pain, crude touch on the left side Option: C. Loss of stereognosis, proprioception, on the right side Fibres from nucleus gracilis and cuneatus cross and continue as medial lemniscus. So, lesion in medial lemniscus leads to contralateral loss of proprioception, stereognosis Therefore Options A, B and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Amyotrophic lateral sclerosis : It is a degenerative disease which is caused due to damage the cells in the ventral horn. The clinical features involve weakness, atrophy of muscles of hands and arms and later extending to the lower limb.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Contralateral loss of pain and temperature is due to injury of:", "options": [{"label": "A", "text": "Anterior Spinothalamic Tract", "correct": false}, {"label": "B", "text": "Lateral spinothalamic tract", "correct": true}, {"label": "C", "text": "Fasciculus gracilis", "correct": false}, {"label": "D", "text": "Fasciculus cuneatus", "correct": false}], "correct_answer": "B. Lateral spinothalamic tract", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral spinothalamic tract The lateral spinothalamic tract controls pain and temperature • Anterior spinothalamic tract controls crude touch and pressure The Lateral spinothalamic tracts convey sensations of pain, temperature, and crude touch from the contralateral side of the body.</p>\n<p><strong>Highyeild:</strong></p><p>The ascending tracts of the spinal cord Name Function Crossed and uncrossed Beginning Termination 1. Lateral spinothalamic (axons of 2nd order neurons) Pain and temperature from opposite half of body Crosses to opposite side in the same spinal segment Laminae I-IV of posterior grey column (substantia gelatinosa) Forms spinal lemniscus in medulla, reaches posterolateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 2. Anterior spinothalamic (axons of 2nd order pressure neurons Touch (crude) and pressure from opposite half of body Ascends to 2-3 spinal segments to cross to opposite side Laminae I-IV of posterior grey column Joins medial lemniscus in brainstem, reaches posterolateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 3. Fasciculus gracilis (axons of 1st order sensory neurons) (lower limb) Conscious proprioception Discriminatory touch Vibratory sense Stereognosis Uncrossed Dorsal root ganglion cells Relays in nucleus gracilis, 2nd order fibres form medial lemniscus which reaches posterolateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 4. Fasciculus cuneatus (axons of 1st order sensory neurons) (upper limb) Same as above Same as above Same as above Relays in nucleus cuneatus, rest is same as above 5. Posterior spino- cerebellar (axons of 2nd order neurons) Unconscious proprio- ception from individual muscles of lower limb Uncrossed Laminae V, VI of posterior grey column Vermis of cerebellum (via inferior cerebellar peduncle) 6. Anterior spinocere- bellar (axons of 2nd order neurons Unconscious proprio- ception from lower limb as a whole Crosses twice, once in spinal cord and recros- ses in midbrain Laminae V, VI of posterior grey column Vermis of cerebellum (via superior cerebellar peduncle) via recrossing 7. Spino-olivary (axons of 2nd order neurons) Proprioceptive sense Uncrossed Laminae I-IV column Tectum or superior colliculus of midbrain 8. Spinotectal (axons of 2nd order neurons) Afferent limb of reflex movements of eyes and head Crossed Laminae I-IV column</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Anterior Spinothalamic Tract Option: C. Fasciculus gracilis Option: D. Fasciculus cuneatus The Lateral spinothalamic tracts convey sensations of pain, temperature, and crude touch from the contralateral side of the body, so options A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Lateral spinothalamic tract: This tract carries the sensation of pain and temperature. The first neuron fibres start in the dorsal root ganglia. These relay by synapsing with neurons lying in the grey matter of laminae II and III. Pain fibres relay in lamina II (substantia gelatinosa). The second neuron fibres cross immediately to the opposite side close to the central canal and ascend as a tract in the lateral white column of the spinal cord.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The inability to perceive the texture and shape of an object occurs in the lesion of", "options": [{"label": "A", "text": "Lateral spinothalamic tract", "correct": false}, {"label": "B", "text": "Spinocerebellar tract", "correct": false}, {"label": "C", "text": "Corticospinal tract", "correct": false}, {"label": "D", "text": "fasciculus cuneatus and fasciculus gracilis", "correct": true}], "correct_answer": "D. fasciculus cuneatus and fasciculus gracilis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>fasciculus cuneatus and fasciculus gracilis Proprioceptive Sensations: The sensations like deep touch, pressure, tactile localization (the ability to locate exactly the proprioceptive part touched), tactile discrimination (the ability to localize two separate points on the skin that is touched), stereognosis (the ability to recognize shape and texture of an object held in hand) and sense of vibration are carried by fasciculus gracilis and fasciculus cuneatus.</p>\n<p><strong>Highyeild:</strong></p><p>The reflex proprioceptive sensations are carried by dorsal and ventral spinocerebellar tracts. They convey to the cerebellum both exteroceptive (touch) and unconscious proprioceptive impulses arising in the Golgi tendon organ and muscle spindle and are essential for the control of posture.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Lateral spinothalamic tract Option: B. Spinocerebellar tract Option: C. Corticospinal tract The sensations like deep touch, pressure, tactile localisation (the ability to locate exactly the proprioceptive part touched), tactile discrimination (the ability to localize two separate points on the skin that is touched), stereognosis (the ability to recognise the shape of an object held in hand) and sense of vibration are carried by fasciculus gracilis and fasciculus cuneatus. Therefore options A, B and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Anterior spinothalamic tract: This tract carries the fibres for crude touch and pressure, tickle and itch. The first neuron fibres are in the dorsal root ganglia. These relay in the grey matter of the posterior horn or nucleus proprius (laminae III and IV). The second neuron fibres ascend for 1–2 segments and cross to the opposite side in the white commissure and ascend as a tract in the anterior white column of the spinal cord.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An anterolateral cordotomy in a 40-year male patient relieved the pain in the right leg. It was effective because it interrupted:", "options": [{"label": "A", "text": "Left Dorsal Column", "correct": false}, {"label": "B", "text": "Left ventral spinothalamic tract", "correct": false}, {"label": "C", "text": "Left lateral spinothalamic tract", "correct": true}, {"label": "D", "text": "Right lateral spinothalamic tract", "correct": false}], "correct_answer": "C. Left lateral spinothalamic tract", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left lateral spinothalamic tract The Lateral spinothalamic tracts convey sensations of pain, temperature, and crude touch from the contralateral side of the body.</p>\n<p><strong>Highyeild:</strong></p><p>The descending tracts Name Function Crossed and uncrossed Beginning Termination Pyramidal tracts 1.Lateral corticospinal 2.Anterior corticospinal Main motor tract for skillful voluntary movements Facilitates flexors Crosses in medulla Crosses in corresponding spinal segment Motor area of cortex (areas 4, 6) Motor area of cortex (areas 4, 6) Anterior grey column cells (alpha motor neurons) Anterior grey column cells (alpha motor neurons) Extrapyramidal tracts 1. Rubrospinal Efferent pathway for cere- bellum and corpus striatum Crossed Red nucleus of midbrain Alpha and gamma motor neurons of anterior grey column cells 2. Medial reticulospinal Extrapyramidal tract Facilitates extensors Uncrossed Reticular formation of grey matter of pons Alpha and gamma motor neurons of anterior grey column cells 3. Lateral reticulospinal Extrapyramidal tract Facilitates flexors Uncrossed and crossed Reticular formation of grey matter of medulla oblongata Alpha and gamma motor neurons of anterior grey column cells 4. Olivospinal Extrapyramidal tract Uncrossed Inferior olivary nucleus Alpha and gamma motor neurons of anterior grey column cells 5. Lateral vestibulospinal Efferent pathway for equilibratory control Uncrossed Lateral vestibular nucleus Alpha and gamma motor neurons of anterior grey column cells 6. Tectospinal Efferent pathway for visual reflexes Crossed Superior colliculus Alpha and gamma motor neurons of anterior grey column cells 7. Descending auto- nomic fibres Control parasympathetic and sympathetic systems Cerebral cortex hypothalamus reticular formation Parasympathetic and sympathetic out flows</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Left Dorsal Column Option: B. Left ventral spinothalamic tract Option: D. Right lateral spinothalamic tract The Lateral spinothalamic tracts convey sensations of pain, temperature, and crude touch from the contralateral side of the body, so options A, B and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Tabes dorsalis: It occurs during the tertiary stage of syphilis. There are degenerative lesions of dorsal nerve roots and posterior white columns. Its feature is severe pain in the lower limbs, as the disease occurs in the lower thoracic and lumbosacral segments. The lower limbs are mainly affected.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The following marked area is an important structure to relay sensations to the brainstem and subsequently towards the cerebral cortex. Mention the type of neuron found in the marked area –", "options": [{"label": "A", "text": "Multipolar Neurons.", "correct": false}, {"label": "B", "text": "Unipolar neurons.", "correct": false}, {"label": "C", "text": "Bipolar neurons", "correct": false}, {"label": "D", "text": "Psudounipolar neuron", "correct": true}], "correct_answer": "D. Psudounipolar neuron", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391653817-QTDA051006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Psudounipolar neuron The marked structure is the dorsal root ganglia . Each dorsal root of the spinal cord contains at the level of the intervertebral foramen an elongated thickening called spinal ganglion or dorsal root ganglion. It comprises a special type of neuron called a pseudounipolar ganglion.</p>\n<p><strong>Highyeild:</strong></p><p>Types of neuroglial cells Protoplasmic astrocyte Fibrous astrocyte Oligodendrocyte Microglia Cell size Large Large Medium Small, elongated Shape of nucleus Oval, light stained Oval, light stained Small, spherical, dark stained Small, elongated, dark stained Cytoplasmic processes Many, short and thick Many long slender Few, short, beaded Short, thin, spinous Cytoplasm Granular Fibrillar - - Situation Grey matter White matter White matter Grey and white matters Function Blood-brain barrier (BBB BBB Myelination Phagocytosis Embryological origin Neural crest Neural crest Neural crest Mesoderm</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Multipolar neurons – these are the majority of the neurons present in the central nervous system and spinal cord. Option: B. Unipolar neurons- Unipolar neurons only occur in invertebrates, such as flies, and are not present in humans. In invertebrates, unipolar neurons play a role in the glands and muscles. Option: C. Bipolar neurons - olfactory epithelium, the retina of the eye, and ganglia of the vestibulocochlear nerve.</p>\n<p><strong>Extraedge:</strong></p><p>Some common reflexes Name of reflex Way of eliciting Result Comment Biceps jerk Striking biceps brachii tendon Flexion of the elbow joint C5, C6 segments intact Tendon jerks may be exaggerated in upper motor neuron lesion or lost in lower motor neuron lesion Triceps jerk Striking triceps brachii tendon Extension of the elbow joint C7, C8 segments intact Knee jerk Striking the ligamentum patellae Extension of the knee joint L3, L4 segments of spinal cord intact Ankle jerk Striking tendo calcaneus Plantar flexion of the ankle joint S1, S2 segments intact Abdominal reflex Striking a quadrant of abdomen Contraction of abdominal muscles Positive reflex indicates normal pyramidal tract with T7-T12 nerves intact Plantar reflex Scratching the sole of foot from lateral side towards big toe Plantar flexion of the great toe and other toes A normal plantar response indicates intact pyramidal tract Babinski's sign Same as in plantar reflex Dorsiflexion of the great toe and fanning of other toes Babinski's sign indicates pyramidal tract injury, except in infants</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Match the following ascending tract with their 2nd-order neurons. Select the correct answer from the given below code:", "options": [{"label": "A", "text": "a – 3, b – 2, c – 4, d – 1", "correct": true}, {"label": "B", "text": "a – 2, b – 4, c – 1, d – 3", "correct": false}, {"label": "C", "text": "a – 3, b – 2, c – 1, d – 4", "correct": false}, {"label": "D", "text": "a – 2, b – 4, c – 3, d – 1", "correct": false}], "correct_answer": "A. a – 3, b – 2, c – 4, d – 1", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/questionImage-1689318787316-QTDA051007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>a – 3, b – 2, c – 4, d – 1 Neurons of sensory tracts Tracts 1st 2nd Lateral spinothalamic Dorsal root ganglion Substantia gelatinosa Anterior spinothalamic Dorsal root Ganglion Nucleus proprius Fasciculus gracilis Dorsal root ganglion Nucleus gracilis in medulla oblongata Fasciculus cuneatus Dorsal root ganglion Nucleus cuneatus in medulla oblongata Dorsal spinocerebellar Dorsal root ganglion Clarke's column Ventral spinocerebellar Dorsal root ganglion Nucleus proprius </ta</p>\n<p><strong>Highyeild:</strong></p><p>Neurons of sensory tracts Tracts 1st 2nd 3rd Clinical tests Lateral spinothalamic Dorsal root ganglion Substantia gelatinosa Posterolateral ventral nucleus of thalamus 1 Pain with pinprick 2 Temperature with hot and cold water in the test tubes Anterior spinothalamic Fasciculus gracilis Fasciculus cuneatus Dorsal root Ganglion Dorsal root ganglion Dorsal root ganglion Nucleus proprius Nucleus gracilis in medulla oblongata Nucleus cuneatus in medulla oblongata Posterolateral ventral nucleus of thalamus Posterolateral ventral 6 sis nucleus of thalamus 1 Joint sense 2 Vibration sense 3 Tactile localisation 4 Tactile discrimination 5 Rhomberg's test 6.Stereognosis 7 Crude touch 8 Crude pressure Dorsal spinocerebellar Ventral spinocerebellar Dorsal root ganglion Dorsal root ganglion Clarke's column Nucleus proprius Nil Nil All cerebellar tests, like the finger- nose and heel-knee tests for intention tremors</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. a – 2, b – 4, c – 1, d – 3 Option: C. a – 3, b – 2, c – 1, d – 4 Option: D. a – 2, b – 4, c – 3, d – 1 Options B, C and D are incorrect answers as shown in the table above.</p>\n<p><strong>Extraedge:</strong></p><p>Main Somatosensory Pathways to Consciousness Sensation Receptor First-Order Neuron Second-Order Neuron Third-Order Neuron Pathways Destination Pain and temperature Free nerve endings Posterior root ganglion Substantia gelatinosa Ventral posterolateral nucleus of thalamus Lateral spinothalamic, spinal lemniscus Posterior central gyrus Light touch and pressure Free nerve endings Posterior root ganglion Substantia gelatinosa Ventral posterolateral nucleus of thalamus Anterior spinothalamic, spinal lemniscus Posterior central gyrus Discriminative touch, vibratory sense, conscious muscle joint sense Meissner corpuscles, pacinian corpuscles, muscle spindles, tendon organs Posterior root ganglion Nuclei gracilis and cuneatus Ventral posterolateral nucleus of thalamus Fasciculi gracilis and cuneatus, medial lemniscus Posterior central gyrus</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the structure X in the given ascending tract.", "options": [{"label": "A", "text": "Lateral Lemniscus", "correct": false}, {"label": "B", "text": "Spinal lemniscus", "correct": true}, {"label": "C", "text": "Trigeminal lemniscus", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "B. Spinal lemniscus", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391655813-QTDA051008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spinal lemniscus The spinothalamic tract is a part of the anterolateral system or the ventrolateral system, a sensory pathway to the thalamus. From the ventral posterolateral nucleus in the thalamus, sensory information is relayed upward to the somatosensory cortex of the postcentral gyrus.</p>\n<p><strong>Highyeild:</strong></p><p>Comparison of pyramidal and extrapyramidal tracts Pyramidal tracts Extrapyramidal tracts Recent in evolution Older in evolution These comprise only cortico- spinal and corticonuclear tracts These comprise olivospinal, vestibulospinal, tectospinal, reticulospinal, rubrospinal tracts Origin from motor cortex These arise from olivary vesti- bular, tectum (collicular), reticular and red nuclei The impulse passes directly to anterior horn cells Impulse passes by polysynaptic route via cortex, basal ganglia, cerebellum and brainstem Function is to perform voluntary skilled movement Control tone and equilibrium. These facilitate/inhibit flexor/ extensor reflexes Injury leads to increased muscle tone and loss of motor activity Injury leads to increased muscle tone with clasp knife rigidity</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Lateral lemniscus - The lateral lemniscus is a tract of axons in the brainstem that carries information about sound from the cochlear nucleus to various brainstem nuclei and ultimately the contralateral inferior colliculus of the midbrain. Option: C. Trigeminal lemniscus - The trigeminal lemniscus is a part of the brain that conveys tactile, pain, and temperature impulses from the skin of the face, the mucous membranes of the nasal and oral cavities, and the eye, as well as proprioceptive information from the facial and masticatory muscles.</p>\n<p><strong>Extraedge:</strong></p><p>Comparison between lower motor neuron (LMN) and upper motor neuron (UMN) paralyzes LMN paralysis UMN paralysis Muscle tone abolished Muscle tone increased Leads to flaccid paralysis Leads to spastic paralysis Muscles atrophy later No atrophy of muscles Reaction of degeneration seen Reaction of degeneration not seen Tendon reflexes absent Limited damage Ipsilateral Tendon reflexes exaggerated Extensive damage Mostly contralateral Babinski sign negative Babinski sign positive All superficial and deep reflexes lost due to damage to motor pathways Superficial reflexes, like abdominal, cremasteric, plantar, are lost due to damage to corticospinal tracts May affect single muscle group as in poliomyelitis and Bell's palsy Affects many groups of muscles as in hemiplegia. Damage to corticospinal tract removes the inhibitory effect on the super- ficial reflexes, resulting in Babinski positive sign There is loss of control on lower motor neurons, which become hyperactive, leading to spastic paralysis</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You are discussing a case with your professor. Your professor tells you that the patient has a problem with Clark’s column. He then tells you to perform a test to support his statement. Which of the following tests will you perform?", "options": [{"label": "A", "text": "Pinprick to check for pain", "correct": false}, {"label": "B", "text": "Finger nose test", "correct": true}, {"label": "C", "text": "Romberg’s test", "correct": false}, {"label": "D", "text": "Check for crude touch", "correct": false}], "correct_answer": "B. Finger nose test", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Finger nose test The Finger-to-Nose-Test measures smooth, coordinated upper-extremity movement by having the examinee touch the tip of his or her nose with his or her index finger. It is one of the tests to check the functional cerebellum. This is the best possible answer as Clark’s column is the 2nd-order neuron for the dorsal spinocerebellar tract.</p>\n<p><strong>Highyeild:</strong></p><p>The Romberg test is an appropriate tool to diagnose sensory ataxia (a gait disturbance caused by abnormal proprioception involving information about the location of the joints). Examples of conditions include Subacute combined degeneration of the spinal cord (Vitamin B12 deficiency); Posterior cord syndrome (Posterior spinal artery infarction); Hemisection of the spinal cord (Brown Sequard syndrome).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Pinprick is used to check the functioning of the lateral spinothalamic tract. Option: C. Romberg’s test- The Romberg test is a test that measures a person's sense of balance. Specifically, the test assesses the function of the dorsal column of the spinal cord (the dorsal column is responsible for proprioception) Option: D. Check for crude touch- The main function of the spinothalamic tract is to carry pain and temperature via the lateral part of the pathway and crude touch via the anterior part.</p>\n<p><strong>Extraedge:</strong></p><p>The Romberg test, tests the function of the Dorsal Column Medial Lemniscal Pathway, the neural pathways by which sensory information from the peripheral nerves is transmitted to the cerebral cortex.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Most of the ascending tracts cross on either side while traversing across the brainstem. Which of the following ascending fibres crosses twice while making their way up through the brainstem?", "options": [{"label": "A", "text": "Anterior Spinothalamic", "correct": false}, {"label": "B", "text": "Lateral spinothalamic", "correct": false}, {"label": "C", "text": "Anterior spinocerebellar", "correct": true}, {"label": "D", "text": "Posterior spinocerebellar", "correct": false}], "correct_answer": "C. Anterior spinocerebellar", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior spinocerebellar The ventral spinocerebellar tract (or anterior spinocerebellar tract) conveys proprioceptive information from the body to the cerebellum. Historically, it has also been known as Gowers' column. It crosses twice while ascending the brainstem.</p>\n<p><strong>Highyeild:</strong></p><p>Ventral or anterior spinocerebellar tract : The first neuron fibres are the central processes of the dorsal root ganglia. The second neuron fibres are derived from the large cells of the posterior grey column (laminae V, VI) in the lumbar and sacral segments. The second neuron fibres cross to the opposite side. These ascend in the lateral white column of the spinal cord anterior to the fibres of the dorsal spinocerebellar tract to pass through the medulla oblongata and pons. These fibres finally curve along the lateral aspect of the superior cerebellar peduncle and recross with the superior cerebellar peduncle to regain their original side of the origin. Functionally, both spinocerebellar tracts control the coordination and movements of muscles controlling the posture of the body. The ventral tract conveys muscle and joint information from the entire lower limb, while the dorsal tract receives information from individual muscles of the lower limb. Pathway of ventral spinocerebellar tract</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A and B. Both lateral and anterior spinothalamic tracts cross only once towards the opposite side. Option: D. Posterior spinocerebellar tract remains uncrossed Difficulty - easy</p>\n<p><strong>Extraedge:</strong></p><p>Dorsal or posterior spinocerebellar tract: It begins at the level of the 3rd lumbar segment of the spinal cord. The first neuron fibres are the central processes of the dorsal root ganglia. These relay in the dorsal nucleus (thoracic or Clarke’s column) which lies on the medial side of the base of the posterior grey column in these segments. This relay gives rise to second neuron fibers which form the dorsal spinocerebellar tract. This uncrossed tract ascends in the lateral column of the white matter of the spinal cord. Here it is situated as a flattened band at the posterior region of the lateral column, medially in contact with the lateral corticospinal tract. It ascends to the level of medulla oblongata where its fibres pass through inferior cerebellar peduncles to reach the cerebellum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A road traffic accident patient was presented to you in casualty. You noticed the following findings and suggested the diagnosis. What is your probable diagnosis?", "options": [{"label": "A", "text": "Syringomyelia", "correct": false}, {"label": "B", "text": "Brown Sequard syndrome", "correct": true}, {"label": "C", "text": "Unilateral cord lesion", "correct": false}, {"label": "D", "text": "Hereditary spastic paraplegia", "correct": false}], "correct_answer": "B. Brown Sequard syndrome", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391658220-QTDA051011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Brown Sequard syndrome Brown-Séquard's syndrome: This is caused due to hemisection of the spinal cord. Various features are: Below the level of lesion: a. Ipsilateral upper motor neuron paralysis caused by pyramidal tract damage. b. Ipsilateral loss of conscious proprioceptive sensations caused due to damage to posterior white column. c. Contralateral loss of pain and temperature and touch caused due to damage to lateral spino- thalamic and anterior spinothalamic tracts. At the level of lesion: Ipsilateral lower motor neuron paralysis caused due to damage to ventral nerve roots. b. Ipsilateral anaesthesia over the skin of the segment due to injury to the ventral nerve roots. Above the level: Ipsilateral hyperaesthesia above the level of lesion due to irritation of dorsal nerve roots.</p>\n<p><strong>Highyeild:</strong></p><p>Subacute combined degeneration: The posterior and lateral funiculi degenerate bilaterally and it is caused due to deficiency of intrinsic factors which help in the absorption of vitamin B12. The symptoms include upper motor neuron lesions with loss of position and vibratory sensation in lower limbs. In lower motor neuron lesions, there is flaccidity, hyporeflexia, and wasting and it is ipsilateral. If all motor neurons reaching a muscle get affected, the muscle will be fully paralyzed. It will feel flaccid. Since no impulses reach the muscle, it will not respond to reflexes. As a result of denervation, it will atrophy soon. The paralysis is ipsilateral. In upper motor neuron lesions, there is spasticity, and hyperreflexia, usually no wasting, and it is contralateral.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Syringomyelia refers to a cystic collection, or syrinx, that occurs within the spinal cord around the central canal. It is a rare neurogenic disease. As the cyst gets larger, it presses on the spinal cord and interferes with the transmission of nerve impulses. Syringomyelia predominantly presents with sensory symptoms such as pain and temperature insensitivity. Option: C. Partial cord lesion Partial cord lesion (unilateral): In high cervical lesions, there is weakness of finger movements accompanied by dragging of the leg. a. Upper motor neuron paralysis on the side of lesion. Sensory loss: Numbness on the side of lesion Joint position sense and two point discrimi- nation impaired on the side of lesion. Burning pain, pin prick and temperature sensation impaired on the opposite side. Pyramidal fibres synapse with anterior horn cells. These control fine movements of hand and fingers. Extra-pyramidal fibres have multiple synapses. These are concerned with large muscle groups used in posture and locomotion. Option: D . Hereditary spastic paraplegia - Hereditary spastic paraplegia is a general term for a group of rare inherited disorders that cause weakness and stiffness in the leg muscles. Symptoms gradually get worse over time. It's also known as familial spastic paraparesis or Strümpell-Lorrain syndrome.</p>\n<p><strong>Extraedge:</strong></p><p>Syringomyelia (central spinal cord syndrome) : There is a formation of cavities around the central canal usually in the lower cervical region. Its features are: Bilateral loss of pain and temperature occurs due to injury to the decussating fibres of lateral spinothalamic fibres. Bilateral loss of touch occurs due to injury to the anterior spinothalamic tract. As the decussation of lateral and anterior spino- thalamic tracts occurs at different levels, there is dissociated sensory loss. As this disease occurs in the lower cervical and upper thoracic regions, there is a problem in both the upper limbs and the front of the chest. Syringomyelia disrupts the crossing fibres of the anterolateral system. The medial lemniscal system is spared.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 6-year-old boy has been having a fever for the last 5 days. One day he complained of weakness in his right lower limb. Soon he could not support his weight. His mother gave a history of skipping a few vaccination doses. Identify the cause of this pathology.", "options": [{"label": "A", "text": "Bacterial Infection", "correct": false}, {"label": "B", "text": "Viral infection", "correct": true}, {"label": "C", "text": "Congenital", "correct": false}, {"label": "D", "text": "Parasitic infection", "correct": false}], "correct_answer": "B. Viral infection", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Viral infection The given scenario is suggestive of Poliomyelitis caused by poliovirus that belongs to picornaviridae.</p>\n<p><strong>Highyeild:</strong></p><p>Poliomyelitis Poliomyelitis is an acute viral infection of the neurons of the anterior grey columns of the spinal cord and cranial nerve motor nuclei. Immunization has greatly reduced the Incidence of poliomyelitis, which was once a torn disease. Paralysis and muscle wasting follow motor nerve cell death. Lower limb muscles are more often affected than those of the upper limb. In severe poliomyelitis, respiration may be threatened due to paralysis spreading to the intercostal muscles and diaphragm. Muscles of the face, pharynx, larynx, and tongue may also be paralyzed. Improvement usually begins at the end of the first week as the edema In the affected area subsides, and the function returns to the neurons that have not been destroyed.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Bacterial – The closest possible differential diagnosis could be tabes dorsalis which is one of the complications of tertiary syphilis. Option: C. Congenital- the signs and symptoms are not present since birth . Option: D. Parasitic Infection – Parasites can affect CNS but the chances of causing muscle weakness are highly impossible.</p>\n<p><strong>Extraedge:</strong></p><p>Parkinson’s Disease Parkinson’s disease is associated with neuronal degeneration in the substantia nigra and, to a lesser extent, in the Globus pallidus, putamen, and caudate nucleus. The degeneration of the inhibitory nigrostriatal fibres results In a reduction In the release of the neurotransmitter dopamine within the corpus striatum. This leads to hypersensitivity of the dopamine receptors in the postsynaptic neurons In the corpus striatum, which become overactive. The characteristic signs of disease, include tremor and cogwheel rigidity (hyperkinetic activity) and difficulty Initiating voluntary movements, which are slow (hypokinetic activity).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Ascending tracts have 3 orders of neurons where the respective fibre relays. All of the following are axons of 2nd-order neurons except :", "options": [{"label": "A", "text": "Spino - olivary tract", "correct": false}, {"label": "B", "text": "Spino – tectal tract", "correct": false}, {"label": "C", "text": "Anterior spinothalamic tract", "correct": false}, {"label": "D", "text": "Fasciculus gracilis", "correct": true}], "correct_answer": "D. Fasciculus gracilis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fasciculus gracilis Explanation of correct - Only fasciculus gracilis (axons of 1st order sensory neurons).</p>\n<p><strong>Highyeild:</strong></p><p>The ascending tracts of the spinal cord Name Function Crossed uncrossed Beginning Termination 1. Lateral spinothalamic (axons of 2nd order neurons) Pain and temperature from the opposite half of the body Crosses to the opposite side in the same spinal segment Substantia gelatinosa of posterior grey column Forms spinal lemniscus in the medulla reaches the posterolateral ventral nucleus of the thalamus for another relay and ends in areas 3, 1, 2 2. Anterior spinothalamic (axons of 2nd-order neurons) Touch (crude) and pressure from the opposite half of the body Ascends to 2-3 spinal segments to cross to the opposite side Posterior grey column of the opposite side Joins medial lemniscus in brainstem reaches postero- lateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 3. Fasciculus gracilis (axons of 1st order sensory neurons) (lower limb) Conscious proprioception Discriminatory touch Vibratory sense Stereognosis Uncrossed Dorsal root ganglion cells Relays in nucleus gracilis, 2nd order fibres form medial lemniscus which reaches the posterolateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 4. Fasciculus cuneatus (axons of 1st order sensory neurons) (upper limb) Same as above Same as above Same as above Relays in nucleus cuneatus, rest is same as above 5. Posterior spinocerebellar (axons of 2nd-order neurons) Unconscious proprioception from individual muscles of the lower limb Uncrossed Thoracic nucleus of the posterior grey column Vermis of cerebellum (via inferior cerebellar peduncle) 6. Anterior spinocerebellar (axons of 2nd order neurons) Unconscious proprioception from the lower limb as a whole Crosses twice, once in the spinal cord and recrosses in the midbrain Posterior grey column on same side Vermis of the cerebellum (via superior cerebellar peduncle) via recrossing 7. Spino-olivary (axons of 2nd-order neurons) Proprioceptive sense Uncrossed Posterior grey column Dorsal and medial accessory olivary nuclei 8. Spinotectal (axons of 2nd order neurons) The afferent limb of reflex movements of eyes and head towards Crossed Posterior grey column of the opposite side Tectum or superior colliculus of the midbrain</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Spino - olivary tract Option: B. Spino – tectal tract Option: C. Anterior spinothalamic tract Options A, B and C. are axons of 2nd-order neurons.</p>\n<p><strong>Extraedge:</strong></p><p>Main Descending Pathways to the Spinal Cord Pathway Function Origin Site of Crossover Destination Branches to Corticospinal tracts Rapid, skilled, voluntary movements, especially distal ends of limbs Primary motor cortex (area 4), secondary motor cortex (area 6), parietal lobe (areas 3, 1, and 2) Most cross at decussation of pyramids and descend as lateral corticospinal tracts; some continue as anterior corticospinal tracts and cross over at level of destination Internuncial neurons or α motor neurons Cerebral cortex, basal nuclei, red nucleus, olivary nuclei, reticular formation Reticulospinal tracts Inhibit or facilitate voluntary movement; hypothalamus controls sympathetic, para-sympathetic outflows Reticular formation Some cross at various levels a and y motor neurons Multiple branches as they descend Tectospinal tract Reflex postural movements concerning sight Superior colliculus Soon after origin α and y motor neurons ? Rubrospinal tract Facilitates activity of flexor muscles and inhibits activity of extensor muscles Red nucleus Immediately α and y motor neurons ? Vestibulospinal tract Facilitates activity of extensor inhibits flexor muscles Vestibular nuclei Uncrossed α and y motor neurons ? Olivospinal tract ?? Inferior olivary nuclei Cross in brainstem Cross in brainstem - Descending autonomic fibers Control sympathetic and parasympathetic systems Cerebral cortex, hypothalamus, amygdaloid complex, reticular formation Sympathetic and parasympathetic outflows -</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Below is a finding noted in a patient, aged 30yr, male presented at your OPD with loss of sensitivity to pain or hot and cold, especially in the hands. What is your probable diagnosis?", "options": [{"label": "A", "text": "Syringomyelia", "correct": true}, {"label": "B", "text": "Brown Sequard syndrome", "correct": false}, {"label": "C", "text": "Unilateral cord lesion", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Syringomyelia", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391660189-QTDA051014IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Syringomyelia Syringomyelia (central spinal cord syndrome): There is a formation of cavities around the central canal usually in the lower cervical region. There is a formation of cavities around the spinal canal. Its features are Bilateral loss of pain and temperature occurs due to injury to the decussating fibres of lateral spinothalamic fibres. b. Bilateral loss of touch occurs due to injury to there is dissociated sensory loss. As this disease occurs in lower cervical and upper anterior spinothalamic tract. As the decussation of lateral and anterior spinothalamic tracts occurs at different levels, thoracic regions there is problem in both the upper limbs and front of chest. Syringomyelia disrupts the crossing fibres of anterolateral system. The medial lemniscal system is spared.</p>\n<p><strong>Highyeild:</strong></p><p>Syringomyelia is a generic term referring to a disorder in which a cyst or cavity forms within the spinal cord. Often, syringomyelia is used as a generic term before an etiology is determined. This cyst called a syrinx, can expand and elongate over time, destroying the spinal cord. The damage may result in loss of feeling, paralysis, weakness, and stiffness in the back, shoulders, and extremities. Syringomyelia may also cause a loss of the ability to feel extremes of hot or cold, especially in the hands. It may also lead to a cape-like bilateral loss of pain and temperature sensation along the upper chest and arms. The combination of symptoms varies from one patient to another depending on the location of the syrinx within the spinal cord, as well as its extent.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option B- Brown-Séquard's syndrome: This is caused due to hemisection of the spinal cord. Various features are: Below the level of lesion: Ipsilateral upper motor neuron paralysis caused by pyramidal tract damage. b. Ipsilateral loss of conscious proprioceptive sensations caused due to damage to posterior white column. Contralateral loss of pain and temperature and touch caused due to damage to lateral spino- thalamic and anterior spinothalamic tracts. At the level of lesion: a. Ipsilateral lower motor neuron paralysis caused due to damage to ventral nerve roots. b. Ipsilateral anaesthesia over the skin of the segment due to injury to the ventral nerve roots. Above the level: Ipsilateral hyperaesthesia above the level of lesion due to irritation of dorsal nerve roots. Option C - Partial cord lesion - Partial cord lesion (unilateral): In high cervical lesions, there is weakness of finger movements accompanied by dragging of the leg. Upper motor neuron paralysis on the side of lesion. b. Sensory loss: Numbness on the side of lesion. Joint position sense and two point discrimi- nation impaired on the side of lesion. c. Burning pain, pin prick and temperature sensation impaired on the opposite side. Pyramidal fibres synapse with anterior horn cells. These control fine movements of hand and fingers. Extra-pyramidal fibres have multiple synapses. These are concerned with large muscle groups used in posture and locomotion.</p>\n<p><strong>Extraedge:</strong></p><p>The shape of horns in different segments of the spinal cord Segments of spinal cord Posterior horn Lateral horn Anterior horn Cervical, oval shape Slender Absent Narrow in 1-3 segments Broad in C4 to C8 segments for supply of upper limbs Thoracic, circular shape Slender Present for thoracolumbar outflow Slender in T2-T12 segments, broad in T1 segment Lumbar, circular shape Bulbous Present only in lumbar 1 and 2 segments Bulbous for supply of lower limbs Sacral, circular but smaller Thick Group of cells in sacral 2-4 segments for sacral outflow Bulbous for supply of lower limbs</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Mention the function of marked areas A and B.", "options": [{"label": "A", "text": "A receives touch sensations from the upper limbs, and B receives touch sensations from the lower limbs.", "correct": true}, {"label": "B", "text": "B receives touch sensations from the upper limbs, and A receives touch sensations from the lower limbs.", "correct": false}, {"label": "C", "text": "A receives pain sensations from the upper limbs, and B receives pain sensations from the lower limbs.", "correct": false}, {"label": "D", "text": "B receives pain sensations from the upper limbs, and A receives pain sensations from the lower limbs.", "correct": false}], "correct_answer": "A. A receives touch sensations from the upper limbs, and B receives touch sensations from the lower limbs.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391661887-QTDA051015IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A receives touch sensations from the upper limbs, and B receives touch sensations from the lower limbs. The gracile fasciculus carries sensory information from the lower half of the body entering the spinal cord at the lumbar level. The cuneate fasciculus carries sensory information from the upper half of the body (upper limbs, trunk, and neck) entering the spinal cord at the cervical level. They both relay into their respective nucleus.</p>\n<p><strong>Highyeild:</strong></p><p>The Romberg test, tests the function of the Dorsal Column Medial Lemniscal Pathway, the neural pathways by which sensory information from the peripheral nerves is transmitted to the cerebral cortex.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options C and D . Touch sensations are carried by lateral spinothalamic tracts and not anterior spinothalamic tracts.</p>\n<p><strong>Extraedge:</strong></p><p>The finger-nose test is used to assess the coordinated, target-driven movement of the upper limb; this is lost in the context of cerebellar pathology.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 25 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 58-year-old male, with a past history of ischemic heart disease for 10 years duration was admitted with a sudden onset seizure episode. After recovery from the postictal state, his wife noticed that he had difficulty in hearing. He was speaking abnormally, repeating each and every word, and not listening to anyone. His tympanic membrane and ossicles were normal. There was no response to the tuning fork and audiometry show SNHL. A computed tomography scan of the brain revealed bilateral acute infarcts in both temporal lobes. What is your diagnosis?", "options": [{"label": "A", "text": "Cortical Deafness", "correct": true}, {"label": "B", "text": "Tinnitus", "correct": false}, {"label": "C", "text": "Hyperacusis", "correct": false}, {"label": "D", "text": "Dysarthria", "correct": false}], "correct_answer": "A. Cortical Deafness", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cortical Deafness Cortical deafness is a severe and rare form of deafness whereby a patient is unresponsive to all types of sounds. Auditory agnosia means the inability to recognize sounds, different musical notes, or words.</p>\n<p><strong>Highyeild:</strong></p><p>Cortical deafness is caused by bilateral cortical lesions in the primary auditory cortex located in the temporal lobes of the brain. The ascending auditory pathways are damaged, causing a loss of perception of sound. Inner ear functions, however, remain intact. Cortical deafness is most often caused by stroke, but can also result from brain injury or birth defects. More specifically, a common cause is a bilateral embolic stroke to the area of Heschl's gyri.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Ringing or buzzing noise in one or both ears that may be constant or come and go, often associated with hearing loss. Option: C. Hyperacusis is a disorder in loudness perception. Patients suffering from hyperacusis may appear overly sensitive to a range of sounds, finding many noises unbearable and painfully loud. Mainly seen nerve to stapedius lesion Option: D. Slurred speech is usually seen in Weakness in the muscles used for speech, which often causes slowed or slurred speech.</p>\n<p><strong>Extraedge:</strong></p><p>Cortical deafness is a rare form of sensorineural hearing loss caused by damage to the primary auditory cortex. Cortical deafness is an auditory disorder where the patient is unable to hear sounds but has no apparent damage to the structures of the ear.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient presented with hearing loss after exposure to loud sounds. From investigation hearing loss were SNHL and damaged organ of Corti. Which among the following in the auditory pathway innervates the organ of Corti?", "options": [{"label": "A", "text": "Peripheral process of spiral ganglion", "correct": true}, {"label": "B", "text": "Central process of spiral ganglion", "correct": false}, {"label": "C", "text": "Fibers from the superior olivary nucleus", "correct": false}, {"label": "D", "text": "Fibers from lateral lemniscus", "correct": false}], "correct_answer": "A. Peripheral process of spiral ganglion", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Peripheral process of spiral ganglion The first neurons of the pathway are located in the spiral ganglion. They are bipolar. Their peripheral processes innervate the spiral organ of Corti.</p>\n<p><strong>Highyeild:</strong></p><p>Auditory Neural Pathways The cell bodies of first-order sensory neurons of the auditory pathways lie in the spiral (cochlear) ganglion which is located within the cochlear modiolus. These neurons are bipolar. Their peripheral processes reach the organ of Corti which is the end organ (receptor organ) for hearing, while the central processes constitute the cochlear nerve, which enters the brainstem at the junction of the medulla and pons. The fibres bifurcate, one branch ending in the dorsal cochlear nucleus and the other in the ventral cochlear nucleus. Auditory pathway Create the flowchart</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Central process of spiral ganglion The central processes of the spiral ganglion constitute the cochlear nerve, which enters the brainstem at the junction of the medulla and pons. Option: C. Fibers from the superior olivary nucleus The fibres from the dorsal nucleus of the trapezoid body and the superior olivary nucleus of both sides ascend as the lateral lemnisci. Option: D. Fibers from lateral lemniscus The lateral lemniscus is the principal ascending auditory tract. It ascends from the region of the superior olivary nucleus, through the lateral part of the pontine tegmentum and close to the surface of the brainstem A few of its fibres relay in the nucleus of the inferior colliculus (centre for auditory reflexes) for reflex activity, Which sends new sets of axons to the medial geniculate body through the brachium of the inferior colliculus. However, most of the fibres of the lateral lemniscus pass directly to the medial geniculate body without being relayed in the inferior colliculus.</p>\n<p><strong>Extraedge:</strong></p><p>The medial geniculate bodies are the final relay stations of the hearing pathway. The fibres arising from medial geniculate bodies (fourth-order sensory neurons) form the auditory radiations which run through the sub lentiform part of the internal capsule to project into the anterior transverse temporal gyrus (or Heschl's gyrus) located on the upper surface of the superior temporal gyrus partly buried in the lateral sulcus. The Heschl's gyrus contains the primary auditory cortex (areas 41 and 42 of Brodmann)</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 35-year-old male patient presented with complaints of inability to maintain the body in a fixed posture. His static balance is altered. Which of the following area contains utricle and saccule fibres from vestibular receptors which maintain static balance?", "options": [{"label": "A", "text": "Inferior Vestibular Area", "correct": true}, {"label": "B", "text": "Foramen singular", "correct": false}, {"label": "C", "text": "Auditory area", "correct": false}, {"label": "D", "text": "Stylomastoid foramen", "correct": false}], "correct_answer": "A. Inferior Vestibular Area", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior Vestibular Area Most of the fibres from the maculae of the utricle and saccule lie in the inferior vestibular area. The vestibule lies between the semicircular canals and the cochlea (eardrum). The vestibule is responsible for maintaining static equilibrium while the semicircular canals maintain dynamic equilibrium.</p>\n<p><strong>Highyeild:</strong></p><p>The static labyrinth detects the position of the head with respect to gravity, although it also responds to linear acceleration or deceleration, i.e. a car that slows down or speeds. The receptors for static balance are maculae in the wall of the utricle and saccule. The macula is a specialized patch of epithelium in the wall of the utricle and saccule. It consists of columnar supporting cells and hair cells. The hair of these cells which consists of numerous microvilli, called stereocilia, and cilium ( kinocilium ) that arise from centriole, is embedded into a gelatinous mass containing irregularly shaped concretions ( otoliths ) composed of protein and calcium carbonate. The gelatinous mass moves in response to gravity, bending the hair cells and initiating the action potentials in the associated neurons.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Foramen singular- In the temporal bone, in the portion beneath the falciform crest are three sets of foramina; one group, just below the posterior part of the crest, situated in the area cribrosa media, consists of several small openings for the nerves to the saccule; below and behind this area is the foramen singular , or opening for the nerve to the posterior semicircular canal. Fibres of crista of posterior semicircular canal lie in foramen singulare. Option: C. The fifth neurons of the auditory pathway lie in the medial geniculate body. Their axons form the auditory radiation, which passes through the sub-lentiform part of the internal capsule to reach the auditory area. Option: D. The stylomastoid foramen, located immediately posterior to the base of the styloid process, is for the exit of the facial nerve (cranial nerve 7) and the entrance of the stylomastoid artery.</p>\n<p><strong>Extraedge:</strong></p><p>The kinetic labyrinth consists of three semicircular ducts. The kinetic labyrinth is involved in evaluating the movements of the head and has a special role in the coordination of eye movements with movements of the head.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 55-year-old male Patient presented to the OPD with complaints of hearing defect, and sharpness of hearing is impaired. He had a past history of cerebrovascular accidents in which he had some ischemic changes in the temporal lobe. On audiometry examination, there was no hearing loss. What would be the probable cause for this condition?", "options": [{"label": "A", "text": "Bilateral cortical representation of the auditory pathway", "correct": true}, {"label": "B", "text": "Unilateral cortical representation of the auditory pathway", "correct": false}, {"label": "C", "text": "Fibers in inferior colliculus", "correct": false}, {"label": "D", "text": "Fibers from lateral lemniscus", "correct": false}], "correct_answer": "A. Bilateral cortical representation of the auditory pathway", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Bilateral cortical representation of the auditory pathway The auditory pathway from the medulla upwards projects about equally into the two cerebral hemispheres. Consequently, the unilateral lesion of the auditory cortex produces only a slight effect on the auditory acuity and which is difficult to detect by audiometry.</p>\n<p><strong>Highyeild:</strong></p><p>Cortical deafness is caused by bilateral cortical lesions in the primary auditory cortex located in the temporal lobes of the brain. The ascending auditory pathways are damaged, causing a loss of perception of sound. Inner ear functions, however, remain intact. Cortical deafness is most often caused by stroke, but can also result from brain injury or birth defects. More specifically, a common cause is a bilateral embolic stroke to the area of Heschl's gyri.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Cortex has bilateral representations thus there is a mild defect in sharpness of hearing. Option C. Some fibres relay in the nucleus of the inferior colliculus for reflex activity which sends a new set of axons to the medial geniculate body From the medial geniculate body forms auditory radiation and project to the auditory area of the brain. Option D. The lateral lemniscus is the principal ascending auditory It ascends from the region of the superior olivary nucleus, through the lateral part of the pontine tegmentum and close to the surface of the brainstem.</p>\n<p><strong>Extraedge:</strong></p><p>Cortical deafness is a rare form of sensorineural hearing loss caused by damage to the primary auditory cortex. Cortical deafness is an auditory disorder where the patient is unable to hear sounds but has no apparent damage to the structures of the ear.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 32-year-old female presented with complaints of a spinning sensation, swaying, headache and vomiting. The clinician diagnosed it as vertigo. Where did the vestibular nuclei send the fibres to?", "options": [{"label": "A", "text": "Archicerebellum", "correct": false}, {"label": "B", "text": "Brainstorm", "correct": false}, {"label": "C", "text": "Spinal cord", "correct": false}, {"label": "D", "text": "All of these", "correct": true}], "correct_answer": "D. All of these", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of these The second neuron in the pathway of balance lies in the vestibular nuclei. These nuclei send fibres to the brainstem, vestibular nuclei and spinal cord.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. To the archicerebellum through the inferior cerebellar peduncle (vestibulocerebellar tract) . Option: B. To the motor nuclei of the brainstem (c hiefly of the III, IV, VI and XI nerves) through the medial longitudinal bundle. Option: C. To the anterior horn cells of the spinal cord through the vestibulospinal Fibres also reach the thalamus and premotor cortex of the frontal lobe.</p>\n<p><strong>Extraedge:</strong></p><p>The second-order sensory neurons of vestibular nuclei project: (a) to the flocculonodular lobe of the cerebellum (archicerebellum) through the inferior cerebellar peduncle (vestibulocerebellar tract), (b) to the motor nuclei of IIIrd, IVth and VIth cranial nerves through medial longitudinal fasciculus (MLF), and (c) to the anterior horn cells of the spinal cord (vestibulospinal tract). The vestibular nuclei also project to the posteroventral nucleus of the thalamus. The third-order sensory neurons from the thalamus project to the vestibular area of the cerebral cortex in the postcentral gyrus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old man presented with complaints of a ringing sensation and hearing loss in his right ear for 3 weeks. The doctor advised earwax removal and hearing aids. Which of the neurons of the auditory pathway forms lateral lemniscus?", "options": [{"label": "A", "text": "First Order", "correct": false}, {"label": "B", "text": "Second order", "correct": false}, {"label": "C", "text": "Third order", "correct": true}, {"label": "D", "text": "Fourth order", "correct": false}], "correct_answer": "C. Third order", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Third order Both the superior olivary nuclei and the lateral lemniscus nucleus comprise the third-order neurons. The subcortical auditory centre is formed by the medial geniculate body, where the fibres of third-order neurons terminate.</p>\n<p><strong>Highyeild:</strong></p><p>Neurons order Ascending auditory pathways First-order neurons Bipolar neurons of spiral ganglion in the cochlear nerve Second-order neurons Dorsal and ventral cochlear nuclei Third-order neurons Superior olivary complex in the pons. From here fibres travel in the lateral lemniscus in the pons Fourth-order neurons Inferior colliculus in the midbrain Fifth-order neurons Medial geniculate body in thalamus. From here fibres go to the auditory cortex in the temporal lobe of the cerebrum through the auditory radiations in the sub-lentiform part of the internal capsule</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The first neurons of the pathway are located in the spiral ganglion. They are bipolar. Their peripheral processes innervate the spiral organ of Corti, while central processes form the cochlear nerve. This nerve terminates in the dorsal and ventral cochlear nuclei. Option: B. The second neurons lie in the dorsal and ventral cochlear nuclei. Most of the axons arising in these nuclei cross to the opposite side (in the trapezoid body) and terminate in the superior olivary nucleus. (Many fibres end in the nucleus of the trapezoid body or of the lateral lemniscus.) Some fibres are uncrossed. Option: D. The fourth neurons lie in the inferior colliculus. Their axons pass through the inferior brachium to reach the medial geniculate body. (Some fibres of lateral lemniscus reach the medial geniculate body without relaying in the inferior colliculus.)</p>\n<p><strong>Extraedge:</strong></p><p>The lateral lemniscus is a tract of axons in the brainstem that carries information about sound from the cochlear nucleus to various brainstem nuclei and ultimately the contralateral inferior colliculus of the midbrain. The function of the complex of Nuclei of the lateral lemniscus is not known; however, it has good temporal resolution compared to other cells higher than the cochlear nuclei and is sensitive to both timing and amplitude changes in sound. It is also involved in the acoustic startle reflex.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 42-year-old male presented with complaints of hearing loss in his right ear for 2 days. He had a history of exposure to sudden loud noise 2 days back. On examination, Rinnes test AC>BC, Weber's test is lateralized to the unaffected ear. Audiogram shows sensorineural hearing loss. Arrange the auditory pathway in order.", "options": [{"label": "A", "text": "Spiral ganglion- superior olivary nuclei- cochlear nuclei- inferior colliculi- MGB- the auditory cortex", "correct": false}, {"label": "B", "text": "Spiral ganglion- superior olivary nuclei- inferior colliculi- cochlear nuclei- MGB- the auditory cortex", "correct": false}, {"label": "C", "text": "Superior olivary nuclei- spiral ganglion- inferior colliculi- cochlear nuclei- MGB- the auditory cortex", "correct": false}, {"label": "D", "text": "Spiral ganglion- cochlear nuclei- superior olivary nuclei- inferior colliculi- MGB- auditory cortex.", "correct": true}], "correct_answer": "D. Spiral ganglion- cochlear nuclei- superior olivary nuclei- inferior colliculi- MGB- auditory cortex.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spiral ganglion- cochlear nuclei- superior olivary nuclei- inferior colliculi- MGB- auditory cortex. MGB- the auditory cortex The first neurons of the pathway are located in the spiral ganglion. They are bipolar. Their peripheral processes innervate the spiral organ of Corti, while central processes form the cochlear nerve. The second neurons lie in the dorsal and ventral cochlear nuclei. Most of the axons arising in these nuclei cross to the opposite side (in the trapezoid body) and terminate in the superior olivary nucleus. The third neurons lie in the superior olivary nucleus. Their axons form the lateral lemniscus and reach the inferior colliculus. The fourth neurons lie in the inferior colliculus. Their axons pass through the inferior brachium to reach the medial geniculate body. The fifth neurons lie in the medial geniculate Their axons form the auditory radiation, which passes through the sub lentiform part of the internal capsule to reach the auditory area in the temporal lobe.</p>\n<p><strong>Highyeild:</strong></p><p>Auditory pathway</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - The correct order of the auditory pathway is Spiral ganglion- cochlear nuclei- superior olivary nuclei- inferior colliculi- MGB- auditory cortex, therefore all other options are incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>Each ear is represented bilaterally in the auditory pathway from the medulla upwards and projects about equally into the two cerebral hemispheres. Consequently, the unilateral lesions of the auditory cortex produce only a slight effect on the auditory acuity (i.e. sharpness of hearing) which is difficult to detect by audiometry testing.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "All are nuclei of basal ganglia, except", "options": [{"label": "A", "text": "Caudate Nucleus", "correct": false}, {"label": "B", "text": "Amygdaloid nucleus", "correct": false}, {"label": "C", "text": "Lentiform nucleus", "correct": false}, {"label": "D", "text": "Dentate nucleus", "correct": true}], "correct_answer": "D. Dentate nucleus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Dentate nucleus Dentate nucleus is a part of the cerebellum.</p>\n<p><strong>Highyeild:</strong></p><p>The basal nuclei are subcortical and intracerebral masses of gray matter forming important parts of the extrapyramidal system. They include the following: The corpus striatum, which is partially divided by the internal capsule into two nuclei: The caudate nucleus. The lentiform nucleus. These two nuclei are interconnected by a few bands of gray matter below the anterior limb of the internal capsule. The bands give it a striped appearance, hence the name. The lentiform nucleus is divided into a lateral part, the putamen, and a medial part, the globus pallidus. The caudate nucleus and putamen (neostriatum) are often grouped as the striatum, whereas the globus pallidus (paleostriatum) is the pallidum. The amygdaloid body also forms a part of the limbic system. Claustrum. Parts of Basal ganglia</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Caudate Nucleus The basal nuclei are subcortical and intracerebral masses of gray matter forming important parts of the extrapyramidal system. It is consist of: The corpus striatum, which is partially divided by the internal capsule into two nuclei: The caudate nucleus. The lentiform nucleus. Option: B. Amygdaloid nucleus The amygdaloid complex and the claustrum were considered parts of the basal ganglia. The amygdaloid body forms a part of the limbic system. Option: C. Lentiform nucleus The four nuclei of basal ganglia (caudate, lentiform, amygdaloid and claustrum) are joined to the cortex at the anterior perforated substance.</p>\n<p><strong>Extraedge:</strong></p><p>The deep cerebellar nuclei (DCN) consist of three nuclei: the fastigial (medial) nucleus, the interposed nucleus, and the dentate (lateral) nucleus. Together they form the sole output of the cerebellum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Incorrect statement regarding the marked areas in the given H.S of the brain is.", "options": [{"label": "A", "text": "A form the roof and lateral wall of the posterior horn of Lateral ventricle", "correct": false}, {"label": "B", "text": "B along with caudate nucleus is referred as corpus striatum", "correct": false}, {"label": "C", "text": "C is the elevation produced by Tapetum fibers", "correct": true}, {"label": "D", "text": "D fibers sweeping forward from genu to connect frontal lobes", "correct": false}], "correct_answer": "C. C is the elevation produced by Tapetum fibers", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391762844-QTDA053002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C is the elevation produced by Tapetum fibers C is the BULB OF POSTERIOR HORN produced by FORCEPS MAJOR FIBERS.</p>\n<p><strong>Highyeild:</strong></p><p>On either side of the corpus callosum, the fibers radiate in the white substance and pass to the various parts of the cerebral cortex; those curving forward from the genu into the frontal lobe constitute the forceps anterior, and those curving backward into the occipital lobe, the forceps posterior. Between these two parts is the main body of the fibers which constitute the tapetum and extend laterally on either side into the temporal lobe, and cover in the central part of the lateral ventricle. Horizontal section of Brain</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. is Tapetum fibers and they sweep backwards and downwards to form the roof and lateral wall of the posterior horn of lateral ventricle. Option B. is lentiform nucleus which along with caudate nucleus is called as corpus striatum Option D. is forceps minor sweeping forwards from the Genu to connect the frontal lobe of cerebrum.</p>\n<p><strong>Extraedge:</strong></p><p>The forceps major, also known as the posterior forceps, is a white matter fiber bundle which connects the occipital lobes and crosses the midline via the splenium of the corpus callosum. The forceps minor, also known as the anterior forceps, is a white matter fiber bundle which connects the lateral and medial surfaces of the frontal lobes and crosses the midline via the genu of the corpus callosum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In the image given below, the structure marked with the arrow is an important area related to the motor function. All of the following give afferent fibers to this structure except:", "options": [{"label": "A", "text": "Thalamus", "correct": false}, {"label": "B", "text": "Cerebral cortex", "correct": false}, {"label": "C", "text": "Substantia Nigra", "correct": false}, {"label": "D", "text": "Spinal cord", "correct": true}], "correct_answer": "D. Spinal cord", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391762877-QTDA053003IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spinal cord Marked structure is caudate nucleus, which receives afferents from cerebrum, thalamus and substantia nigra. The caudate nucleus is one of the structures that make up the corpus striatum, which is a component of the basal ganglia in the human brain.</p>\n<p><strong>Highyeild:</strong></p><p>Connections of Corpus striatum Connections of the corpus striatum Nucleus Afferents Efferents A. Caudate nucleus and putamen From: 1. Cerebral cortex (areas 4 and 6) 2. Thalamus (medial, intralaminar and midline nuclei) 3. Substantia nigra Chiefly to globus pallidus, but also to substanti nigra and thalamus B. Globus pallidus Mainly from: 1. Caudate nucleus 2. Putamen Also from: 1. Thalamus 2. Subthalamic nucleus 3. Substantia nigra Efferents form three bundles, namely: 1. Ansa lenticularis, ventrally 2. Fasciculus lenticularis, dorsally 3. Subthalamic fasciculus from the middle par of the globus pallidus These bundles terminate in the following: 1. Thalamus 2. Hypothalamus 3. Subthalamic nucleus 4. Red nucleus 5. Olivary nucleus 6. Substantia nigra 7. Reticular nuclei</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Thalamus Option B. Cerebral cortex Option C. Substantia Nigra Marked structure is caudate nucleus, which receives afferents from cerebrum, thalamus and substantia nigra.</p>\n<p><strong>Extraedge:</strong></p><p>The caudate is highly innervated by dopaminergic neurons that originate from the substantia nigra pars compacta (SNc). The SNc is located in the midbrain and contains cell projections to the caudate and putamen, utilizing the neurotransmitter dopamine. There are also additional inputs from various association cortices.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An important area of basal ganglia is marked in the given figure. Injury to the following marked area X will result in which of the following clinical findings? Create the Image and remove the labeling and mark X as shown in the image", "options": [{"label": "A", "text": "Athetosis", "correct": true}, {"label": "B", "text": "Hemiballismus", "correct": false}, {"label": "C", "text": "Intentional tremors", "correct": false}, {"label": "D", "text": "Myoclonus", "correct": false}], "correct_answer": "A. Athetosis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391763668-QTDA053004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Athetosis X marked structure is, Globus Pallidus Athetosis refers to the slow, involuntary, and writhing movements of the limbs, face, neck, tongue, and other muscle groups. The fingers are also affected, with their flexing happening separately and irregularly. The hands move, and the toes and feet may also experience the effect. It is seen in the lesion of globus pallidus.</p>\n<p><strong>Highyeild:</strong></p><p>Athetosis is a symptom characterized by slow, involuntary, convoluted, writhing movements of the fingers, hands, toes, and feet and in some cases, arms, legs, neck and tongue. Movements typical of athetosis are sometimes called athetoid movements. Lesions to the brain are most often the direct cause of the symptoms, particularly to the corpus striatum . This symptom does not occur alone and is often accompanied by the symptoms of cerebral palsy, as it is often a result of this physical disability. Treatments for athetosis are not very effective, and in most cases are simply aimed at managing the uncontrollable movement, rather than the cause itself. Horizontal section of the cerebral hemisphere</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. hemiballismus -Hemiballismus is a hyperkinetic involuntary movement disorder characterized by intermittent, sudden, violent, involuntary, flinging, or ballistic high amplitude movements involving the ipsilateral arm and leg caused by dysfunction in the sub thalamic nucleus of the contralateral side. Option: C. intentional tremors - Intention tremor is defined as a rhythmic, oscillatory, and high amplitude tremor during a directed and purposeful motor movement, worsening before reaching the endpoint. It is caused by lesions in cerebellar pathways. Option: D. myoclonus - Myoclonus refers to sudden, brief involuntary twitching or jerking of a muscle or group of muscles.</p>\n<p><strong>Extraedge:</strong></p><p>Hemiballismus or hemiballism is a basal ganglia syndrome resulting from damage to the subthalamic nucleus in the basal ganglia . Hemiballismus is a rare hyperkinetic movement disorder ,that is characterized by violent involuntary limb movements, on one side of the body and can cause significant disability.Ballismus affects both sides of the body and is much rarer.Symptoms can decrease during sleep. Hemiballismus differs from chorea in that the movements occur in the proximal limbs whereas in chorea the limb movements are in the distal limbs. Also in chorea the movements are more dance-like, flowing from one region to another.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is true with respect to basal ganglia?", "options": [{"label": "A", "text": "Caudate nucleus alone is termed as paleostriatum.", "correct": false}, {"label": "B", "text": "Globus pallidus and putamen together is called as neostriatum", "correct": false}, {"label": "C", "text": "Caudate Nucleus And Putamen Together Are Termed As The Corpus Striatum", "correct": true}, {"label": "D", "text": "Lentiform nucleus is made by caudate nucleus and putamen.", "correct": false}], "correct_answer": "C. Caudate Nucleus And Putamen Together Are Termed As The Corpus Striatum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Caudate Nucleus And Putamen Together Are Termed As The Corpus Striatum Corpus Striatum, also called striatum, is an important nucleus present in the forebrain. Corpus striatum is considered to be the largest structure present in basal ganglia. It is divided into two parts, dorsal striatum and ventral striatum. Dorsal Striatum ● It is further divided by the internal capsule into two parts, caudate nucleus, and putamen. Ventral Striatum It is further divided into nucleus accumbens and olfactory tubercle.</p>\n<p><strong>Highyeild:</strong></p><p>Putamen is a round nucleus located at the base of the forebrain. It is continuous with the head of the caudate nucleus. Caudate Nucleus is a large C-shaped mass of gray matter, a head, body, and tail. The head of the caudate nucleus is large and round and forms the anterior horn of the fourth ventricle. It is also continuous with the putamen of the lentiform nucleus. The head is continuous with a linear and narrow-body which in turn tapers into a tail. The tail follows the contour of the lateral ventricle. The tail of the caudate nucleus terminates as the amygdaloid nucleus. Nucleus accumbens is located in the basal forebrain in the preoptic area. It has an outer shell and an inner core. The inner core is a part of the ventral striatum. Most of the neurons in nucleus accumbens are GABAergic neurons. Olfactory tubercle is a processing center that is common to both the olfactory cortex and ventral striatum. It is also located in the basal area of the forebrain.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Paleostriatum is another term used for globus pallidus. Option: B. Putamen and caudate nucleus together called as neostriatum. Option: D. Lentiform nucleus is formed by globus pallidus and putamen together</p>\n<p><strong>Extraedge:</strong></p><p>Ventral striatum is mainly concerned with cognition, reward, and reinforcement. On the other hand, dorsal striatum is mainly associated with the cognition involving motor functions.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statements is false about claustrum?", "options": [{"label": "A", "text": "It is saucer shaped.", "correct": false}, {"label": "B", "text": "It is situated between putamen and insula.", "correct": false}, {"label": "C", "text": "It is thickest inferiorly.", "correct": false}, {"label": "D", "text": "It is continuous with posterior perforating substance.", "correct": true}], "correct_answer": "D. It is continuous with posterior perforating substance.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>It is continuous with posterior perforating substance. It is continuous with posterior perforating substance is false statement as claustrum is continuous with anterior perforating substance.</p>\n<p><strong>Highyeild:</strong></p><p>The blood supply to the claustrum is via the middle cerebral artery . The claustrum is a small bilateral gray matter structure (comprising roughly 0.25% of the cerebral cortex) located deep to the insular cortex and extreme capsule, and superficial to the external capsule and basal ganglia. Claustrum seen in coronal section of brain</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. It is saucer-shaped. Claustrum is a thin saucer-shaped mass of gray matter situated between the putamen and insula . Option: B. It is situated between the putamen and the insula. It is located between the insula laterally and the putamen medially, separated by the extreme and external capsules respectively. Option: C. It is thickest inferiorly Claustrum is thickest inferiorly. All the other options are correct about claustrum.</p>\n<p><strong>Extraedge:</strong></p><p>The claustrum is a thin, bilateral collection of neurons and supporting glial cells that connects to cortical ( the prefrontal cortex) and subcortical regions (e.g., the thalamus) of the brain. It is located between the insula laterally and the putamen medially, separated by the extreme and external capsules respectively.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Caudate nucleus is a C shaped nucleus which is surrounded by lateral ventricles. The concavity of the caudate nucleus encloses the thalamus and internal capsule. Which of the following statements is false regarding relations of the lateral ventricle to the caudate nucleus?", "options": [{"label": "A", "text": "Floor of the anterior horn is formed by the upper surface of the rostrum of corpus callosum.", "correct": false}, {"label": "B", "text": "The tail of the caudate nucleus forms the roof of the posterior horn of the lateral ventricle.", "correct": true}, {"label": "C", "text": "The body forms the floor of the central part of the lateral ventricle.", "correct": false}, {"label": "D", "text": "Amygdaloid body is connected to the tail of the caudate nucleus.", "correct": false}], "correct_answer": "B. The tail of the caudate nucleus forms the roof of the posterior horn of the lateral ventricle.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The tail of the caudate nucleus forms the roof of the posterior horn of the lateral ventricle. The roof, lateral wall, and floor of the posterior horn of lateral ventricle are formed by a sheet of fibers (tapetum) from the splenium of the corpus callosum. The posteriorly sweeping fibers of the optic radiation remain separated from the cavity of the posterior horn by the tapetum.</p>\n<p><strong>Highyeild:</strong></p><p>There are two lateral ventricles, one in each cerebral hemisphere. Each lateral ventricle is a roughly C-shaped cavity situated within each cerebral hemisphere. The lateral ventricle wraps itself around the thalamus, the lentiform nucleus, and the caudate nucleus. It is lined with ependyma and filled with cerebrospinal fluid. It has a capacity of about 7–10 ml. The main parts of two ventricles are separated from each other by a septum extending between corpus callosum and fornix called septum pellucidum. Lateral ventricle</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Floor of the anterior horn is formed by the upper surface of the rostrum of corpus callosum. The narrow floor of the lateral ventricle is formed by the upper surface of the rostrum of corpus callosum. Option: C. The body forms the floor of the central part of the lateral ventricle. The floor of central part of lateral ventricle slopes downwards from lateral to the medial side and is formed in that order by: Body of caudate nucleus Stria terminalis and thalamostriate vein. Lateral part of the upper surface of the thalamus. Choroid plexus covering the medial part of the upper surface of the thalamus Upper surface of the body of the fornix. Option: D. Amygdaloid body is connected to the tail of the caudate nucleus. Amygdaloid body is connected to the tail of the caudate nucleus as shown in the image above.</p>\n<p><strong>Extraedge:</strong></p><p>The choroid plexus of the lateral ventricle is derived from an anterior choroidal artery, a branch of the internal carotid artery, and the posterior choroidal artery, a branch of the posterior cerebral artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Read the following statements regarding the functions of the corpus striatum and choose the correct statements: It is responsible for the planning and programming of voluntary movements. It determines the speed and range of movements It prevents unwanted muscular activity. It helps the cerebral cortex in the execution of learned patterns of movements subconsciously. It controls the coordinated movements of different parts of the body for emotional expression. Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1, 2, 4, 5", "correct": false}, {"label": "B", "text": "2, 3,5", "correct": false}, {"label": "C", "text": "1, 2,4, 5", "correct": false}, {"label": "D", "text": "1, 2 ,3 ,4 ,5", "correct": true}], "correct_answer": "D. 1, 2 ,3 ,4 ,5", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1, 2 ,3 ,4 ,5 All the statements mentioned in points 1,2,3,4, and 5 are correct regarding the function of the corpus striatum. Below are the few important functions of basal ganglia. Functions of Corpus Striatum The corpus striatum regulates muscle tone and thus helps in smoothening voluntary movements. It controls automatic associated movements, like the swinging of arms during walking. Similarly, it controls the coordinated movements of different parts of the body for emotional expression. It influences the precentral motor cortex which is supposed to control the extrapyramidal activities of the body. These do not receive any sensory input from the spinal cord, unlike the cerebellum. Basal ganglia contribute to the cognitive function of the brain. These help the cortex in the execution of learned patterns of movements subconsciously.</p>\n<p><strong>Highyeild:</strong></p><p>Parkinsonism (also called Parkinson's disease/paralysis agitans) This disease usually occurs after 50 years of age due to a deficiency of the neurotransmitter dopamine in the corpus striatum following a lesion in the substantia nigra and/or its projections (i.e. nigrostriatal fibres). Dopamine is synthesized in the melanin-containing pigmented cells of substantia nigra and transported to the corpus striatum through nigrostriatal fibers. Dopamine causes inhibition of cells within the corpus striatum. The neurological changes in Parkinsonism appear to be a release phenomenon due to a lack of inhibitory influences following dopamine deficiency.</p>\n<p><strong>Extraedge:</strong></p><p>Characteristic features of Parkinsonism Resting tremors , i.e. a slight shaking of hands when a person is not performing a task. The tremors are diminished with movement and exaggerated by emotional excitation. Lead-pipe or cogwheel type of muscular rigidity due to increased muscle tone (in contrast to clasp-knife rigidity of upper motor neuron lesions). Pill-rolling movements of hands, consisting of circular movements of the opposed thumb and index fingertips is a kind of resting tremor). Mask-like face or loss of facial expression, due to lack of control of a group of muscles of movements for emotional expression. Stiff, shuffling gait due to rigidity of joints.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 18 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 55-Year-old woman presents to the clinic complaining of blood in her stools. Physical exam reveals firm, enlarged inguinal lymph nodes. A contrast CT scan is performed and a possibly cancerous mass is visualized in the lower part of the gastrointestinal tract. In which location is the mass most likely located?", "options": [{"label": "A", "text": "Anal canal inferior to the pectinate line", "correct": true}, {"label": "B", "text": "Distal rectum", "correct": false}, {"label": "C", "text": "Sigmoid colon", "correct": false}, {"label": "D", "text": "Proximal rectum", "correct": false}], "correct_answer": "A. Anal canal inferior to the pectinate line", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anal canal inferior to the pectinate line The lymph from the inferior part of the anal canal drains to the superficial inguinal nodes . The lymph from the distal rectum drains to the sacral nodes. The lymph from the sigmoid colon drains to the inferior mesenteric nodes and then to the internal iliac nodes. The lymph from the proximal rectum drains to the sacral nodes, and the lymph from the anal canal above the pectinate line drains to the internal iliac nodes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 48-year-old woman has the sudden onset of abdominal pain 1 day after undergoing abdominal hysterectomy to remove leiomyomata uteri. Abdominal examination shows tenderness over the right lower quadrant. A retrograde pyelogram shows contrast material in the left renal pelvis and none in the right. These findings indicate that a structure was probably damaged during surgery. That structure passes inferior to which of the following?", "options": [{"label": "A", "text": "Ovarian Ligament", "correct": false}, {"label": "B", "text": "Mesosalpinx", "correct": false}, {"label": "C", "text": "Round ligament of the uterus", "correct": false}, {"label": "D", "text": "Uterine artery", "correct": true}], "correct_answer": "D. Uterine artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Uterine artery During hysterectomy, hemostasis may be ensured by proper ligation of the arteries that supply the uterus. The uterine artery, a branch of the internal iliac artery, is anterior to the ureter in the broad ligament of the uterus . During surgeries, the ureter may be ligated mistakenly in the place of the uterine artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The ovarian ligament attaches the ovary to the lateral and superior part of the uterus . It is a fibrous cord that is contained in the broad ligament of the uterus and has no direct relationship with the uterus. Option: B. The Mesosalpinx is the part of the broad ligament that stretches from the ovary to the uterine tube above. Option: C. The round ligament of the uterus is an embryologic remnant of the gubernaculum ovary and has no direct relationship with the uterus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 60-year-old woman with a known history of colon cancer presents to the clinic with abdominal pain. A CT scan reveals spread of her cancer to multiple areas, with subsequent fluid accumulation in her peritoneal cavity. In order to collect this fluid in a minimally invasive manner to test for cancer markers a needle is passed through the posterior vaginal fornix into the peritoneal cavity while the patient is seated upright. From which space is the fluid drained?", "options": [{"label": "A", "text": "Rectouterine Pouch", "correct": true}, {"label": "B", "text": "Pararectal fossa", "correct": false}, {"label": "C", "text": "Paravesical space", "correct": false}, {"label": "D", "text": "Uterovesical pouch", "correct": false}], "correct_answer": "A. Rectouterine Pouch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Rectouterine Pouch The rectouterine pouch (or pouch of Douglas) is the extension of the peritoneal cavity between the rectum and the posterior uterine wall of the uterus in women . It is the most dependent or lowest part of the abdominopelvic cavity when in the supine position making it a typical site for the collection1 of fluids. Due to its intimacy with the posterior wall of the uterus, it can be examined transvaginally or transrectally by digital palpation. Fluids collected there may also be drained through the vagina or rectum without entering the abdominopelvic cavity transabdominal.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. The pararectal fossa is a feature found only in men. Option: C. The paravesical space is made up of paired subdivisions of the extraperitoneal space found lateral to the prevesical space. Option: D. The uterovesical pouch is formed by the peritoneum over the uterus and bladder, continued over the intestinal surface and fundus of the uterus onto its vesical surface.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 30y old male complained that he experiences focal (nonradiating) pain in the buttocks after sitting straight for long hours. The pain immediately resolved when the student stood up. Which of the following bony features was most likely responsible for the student's pain?", "options": [{"label": "A", "text": "Inferior Pubic Ramus", "correct": false}, {"label": "B", "text": "Posterior superior iliac spine", "correct": false}, {"label": "C", "text": "Ischial tuberosity", "correct": true}, {"label": "D", "text": "Pubic tubercle", "correct": false}], "correct_answer": "C. Ischial tuberosity", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ischial tuberosity The rough bony projection at the junction of the inferior end of the body of the ischium and its ramus is the large ischial tuberosity. Much of the upper body’s weight rests on these tuberosities when sitting, and it provides the proximal, tendinous attachment of posterior thigh muscles (hamstring muscles and a portion of the adductor Magnus). The small pointed posteromedial projection near the junction of the ramus and body is the ischial spine.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The inferior pubic ramus is thin and flat and does not bear weight. Option: B. The iliac crest extends posteriorly, terminating at the posterior superior iliac spine. Option: D. The pubic tubercle is a prominent forward projecting tubercle on the upper border of the medial portion of the superior ramus of the pubis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During the physical examination of a 35-year-old man, his urologist palpated the anterolateral surface of the scrotum. This part of the scrotum is most likely innervated by which of the following nerves?", "options": [{"label": "A", "text": "Ilioinguinal Nerve (L1)", "correct": true}, {"label": "B", "text": "Iliohypogastric nerve (L1)", "correct": false}, {"label": "C", "text": "Ilioinguinal nerve (L2)", "correct": false}, {"label": "D", "text": "Pudendal nerve", "correct": false}], "correct_answer": "A. Ilioinguinal Nerve (L1)", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ilioinguinal Nerve (L1) The ilioinguinal nerve is a branch of the first lumbar nerve (L1). Its fibers are distributed to the s kin of the upper and medial part of the thigh , and the skin over the root of the penis and upper part of the scrotum in men and the skin covering the mons pubis and labium majus in women.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 69-year-old man is admitted to the hospital for a scheduled radical prostatectomy. Six months postoperatively the patient visits the outpatient clinic complaint of impotence. Where are the nerve cell bodies located that are responsible for erection?", "options": [{"label": "A", "text": "Sacral Parasympathetic Nucleus", "correct": true}, {"label": "B", "text": "Sacral sympathetic trunk ganglia", "correct": false}, {"label": "C", "text": "Inferior mesenteric ganglion", "correct": false}, {"label": "D", "text": "Superior hypogastric plexus", "correct": false}], "correct_answer": "A. Sacral Parasympathetic Nucleus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sacral Parasympathetic Nucleus The neural cell bodies responsible for erection are located in the sacral parasympathetic nucleus (intermediate medial cell column). The parasympathetic nervous system is responsible for producing an erection.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. - The sacral sympathetic trunk ganglia would not be responsible for the action of erection but rather the action of ejaculation. (Mnemonic: \"Point and Shoot\": parasympathetics for erection, sympathetics for ejaculation.) Option: C. - The inferior mesenteric ganglion would not contain parasympathetic neural cells. bodies responsible for erection because they go to the hindgut. Option: D. - The superior hypogastric plexus contains few if any parasympathetic fibers and is not the primary location for the parasympathetic neural cell bodies.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 42-year-old woman is admitted to the hospital with a mass on her right ovary. An ovariectomy is performed and the lymphatics of the lateral pelvic wall are also removed. Four days postoperatively the patient complains of painful spasms of the adductor muscles of the thigh and sensory deficit in the distal medial thigh. Which of the following nerves is most likely injured?", "options": [{"label": "A", "text": "Genitofemoral", "correct": false}, {"label": "B", "text": "Ilioinguinal", "correct": false}, {"label": "C", "text": "Iliohypogastric", "correct": false}, {"label": "D", "text": "Obturator", "correct": true}], "correct_answer": "D. Obturator", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Obturator The obturator nerve runs a course along the lateral pelvic wall and innervates the adductors of the thigh and the skin on the medial aspect of the distal thigh. Damage to the obturator nerve is the most common cause for the sensory and motor deficit experienced by the patient.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. - The genitofemoral nerve is motor to the cremaster muscle and sensory to the skin over the femoral triangle. Option: B. - The ilioinguinal nerve innervates the skin over the labium majus and upper, inner thigh. Option: C. - The iliohypogastric nerve supplies skin over the anterolateral gluteal region and a strip to the area above the pubis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 23-Year-old woman in her seventh month of pregnancy visits her gynecologist for a routine checkup. The patient is informed that a hormone called \"relaxin\" is responsible for the relaxation of the sacroiliac joint and pubic symphysis. Which of the following pelvic distances will most likely remain unaffected?", "options": [{"label": "A", "text": "Transverse Diameter", "correct": false}, {"label": "B", "text": "Interspinous distance", "correct": false}, {"label": "C", "text": "True conjugate diameter", "correct": true}, {"label": "D", "text": "Diagonal conjugate", "correct": false}], "correct_answer": "C. True conjugate diameter", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>True conjugate diameter The conjugate diameter of the pelvis (anteroposterior) is not altered by relaxation of the pelvic joints.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. - The transverse diameter is the longest distance extending from the middle of one pelvic brim to the< other. Option: B. - The interspinous distance is the distance between the ischial spines and changes dramatically during pregnancy due to relaxation of the joints. Option: D. - The diagonal conjugate and oblique diameters are slightly increased during pregnancy due to the effects of the hormone relaxin.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 38-year-old woman visits her gynecologist for a routine Pap smear examination. During the collection of cells from her uterine cervix she feels a mild pain. Which of the following areas is most likely to experience \"referred pain\" during this procedure?", "options": [{"label": "A", "text": "Perineum and lateral portion of the thigh", "correct": true}, {"label": "B", "text": "Suprapubic region", "correct": false}, {"label": "C", "text": "Umbilical region", "correct": false}, {"label": "D", "text": "Epigastric region", "correct": false}], "correct_answer": "A. Perineum and lateral portion of the thigh", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Perineum and lateral portion of the thigh Pain from this area is mediated via parasympathetic responses and would thus travel to the S2 to S4 levels through the pelvic splanchnic nerves. The S2, S3, and S4 spinal cord levels also provide sensory innervation of the perineum and posterior thigh.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. The suprapubic and inguinal region are supplied by ilioinguinal and iliohypogastric nerves (L1). Option: C. The umbilical region receives sensory innervation from the T10 level. Option: D. In the epigastric region the sensory innervation is provided by T7 to T10.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 34-Year-old man is admitted to the emergency department after a traumatic landing into a swimming pool from a high diving platform. The patient has multiple traumas in his abdominal cavity. After a reconstructive operation of his abdominal organs the patient develops a high fever. Radiographic examination reveals that the lower portion of the descending colon and rectum has become septic and must be excised. Six months postoperatively the patient complains of impotence. Which of the following structures was most likely injured during the second operation?", "options": [{"label": "A", "text": "Pudendal Nerve", "correct": false}, {"label": "B", "text": "Sacral splanchnic nerves", "correct": false}, {"label": "C", "text": "Pelvic splanchnic nerves", "correct": false}, {"label": "D", "text": "Sympathetic trunk", "correct": true}], "correct_answer": "D. Sympathetic trunk", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sympathetic trunk The pelvic splanchnic nerves (nervi erigentes) contain afferent fibers that mediate erection. These same nerves innervate the hindgut, the portions of the large intestine that were removed in this patient.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. The sacral sympathetic trunk ganglia would not be responsible for the action of erection but rather the action of ejaculation. (Mnemonic: \"Point and Shoot\": parasympathetics for erection, sympathetics for ejaculation.) Option: C. The inferior mesenteric ganglion would not contain parasympathetic neural cells. bodies responsible for erection because they go to the hindgut. Option: D. The superior hypogastric plexus contains few if any parasympathetic fibers and is not the primary location for the parasympathetic neural cell bodies.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 20 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Charcot’s artery of cerebral hemorrhage belongs to:", "options": [{"label": "A", "text": "Lateral Striate Group", "correct": true}, {"label": "B", "text": "Medial striate group", "correct": false}, {"label": "C", "text": "Posterior striate group", "correct": false}, {"label": "D", "text": "Anterior striate group", "correct": false}], "correct_answer": "A. Lateral Striate Group", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral Striate Group Lateral striate artery - from a middle cerebral artery - Charcot’s artery of a cerebral hemorrhage.</p>\n<p><strong>Highyeild:</strong></p><p>Charcot–Bouchard aneurysms are aneurysms in the small penetrating blood vessels of the brain. They are associated with hypertension. The common artery involved is the lenticulostriate branch of the middle cerebral artery. Common locations of hypertensive hemorrhages include the putamen, caudate, thalamus, pons, and cerebellum. Charcot–Bouchard aneurysms are a common cause of cerebral hemorrhage. Circle of Willis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Medial striate group The recurrent artery of Heubner, also known as the medial striate artery or long central artery , is the largest perforating branch from the proximal anterior cerebral artery (ACA) and is the only one routinely seen on angiography. The recurrent artery of Heubner provides vascular supply mainly to: head of the caudate nucleus the medial portion of globus pallidus anterior limb of the internal capsule anterior hypothalamus nucleus accumbens parts of the uncinate fasciculus diagonal band of Broca basal nucleus of Meynert Option: C. Posterior striate group Lateral striate artery - from middle cerebral artery - Charcot’s artery of cerebral hemorrhage. Option: D. Anterior striate group Lateral striate artery - from middle cerebral artery - Charcot’s artery of cerebral hemorrhage.</p>\n<p><strong>Extraedge:</strong></p><p>The lenticulostriate arteries are also known as the lateral striate arteries that arise from the middle cerebral artery. The other striate artery is the medial striate artery known as the recurrent artery of Heubner that arises from the anterior cerebral artery. If a Charcot–Bouchard aneurysm ruptures, it will lead to an intracerebral hemorrhage, which can cause hemorrhagic stroke, typically experienced as a sudden focal paralysis or loss of sensation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient suffered head trauma in a road traffic accident. Clinical findings and imaging were suggestive of extradural hemorrhage along with fracture of pterion. Which of the following vessels could be involved in this case?", "options": [{"label": "A", "text": "Accessory middle meningeal artery", "correct": false}, {"label": "B", "text": "Middle cerebral artery", "correct": false}, {"label": "C", "text": "Middle meningeal artery", "correct": true}, {"label": "D", "text": "Superficial temporal artery", "correct": false}], "correct_answer": "C. Middle meningeal artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Middle meningeal artery Extradural hemorrhage - middle meningeal artery The middle meningeal artery is of great surgical importance because it can be torn in head injuries resulting in extradural haemorrhage. The frontal or anterior branch is commonly involved. The haematoma presses on the motor area, giving rise to hemiplegia of the opposite side. Middle meningeal artery</p>\n<p><strong>Highyeild:</strong></p><p>Extradural hematomas are typically biconvex in shape and can cause a mass effect with herniation. They are usually limited by cranial sutures, but not by venous sinuses. Both CT and MRI are suitable to evaluate extradural hematomas. When the blood clot is evacuated promptly (or sufficiently small to be treated conservatively), the prognosis of extradural hematomas is generally good.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Accessory middle meningeal artery Extradural hematoma (EDH) , also known as an epidural hematoma , is a collection of blood that forms between the inner surface of the skull and the outer layer of the dura, which is called the endosteal layer. They are usually associated with a history of head trauma and frequently associated skull fractures. The source of bleeding is most commonly from a torn middle meningeal artery. Option: B. Middle cerebral artery Extradural hematoma (EDH) , also known as an epidural hematoma , is a collection of blood that forms between the inner surface of the skull and the outer layer of the dura, which is called the endosteal layer. They are usually associated with a history of head trauma and frequently associated skull fractures. The source of bleeding is usually arterial, most commonly from a torn middle meningeal artery. Option: D. Superficial temporal artery Extradural hematoma (EDH) , also known as an epidural hematoma , is a collection of blood that forms between the inner surface of the skull and the outer layer of the dura, which is called the endosteal layer. They are usually associated with a history of head trauma and frequently associated skull fractures. The source of bleeding is usually arterial, most commonly from a torn middle meningeal artery.</p>\n<p><strong>Extraedge:</strong></p><p>A typical presentation of a case of extradural hemorrhage is of a young patient who has sustained a head injury (either during sport or a result of a motor vehicle accident) and may or may not lose consciousness transiently. Following the injury, they regain a normal level of consciousness (lucid interval), but usually have an ongoing and often severe headache. Over the next few hours, they gradually lose consciousness.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Cranial nerve lying between the superior cerebellar artery and posterior cerebral artery:", "options": [{"label": "A", "text": "Oculomotor Nerve", "correct": true}, {"label": "B", "text": "Optic nerve", "correct": false}, {"label": "C", "text": "Abducens nerve", "correct": false}, {"label": "D", "text": "Trigeminal nerve", "correct": false}], "correct_answer": "A. Oculomotor Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Oculomotor Nerve The Oculomotor nerve lies between the superior cerebellar artery and posterior cerebral artery. Oculomotor nerve</p>\n<p><strong>Highyeild:</strong></p><p>The oculomotor nerve, also known as the third cranial nerve, cranial nerve III, or simply CN III, is a cranial nerve that enters the orbit through the superior orbital fissure and innervates extraocular muscles that enable most movements of the eye and that raise the eyelid. The nerve also contains fibers that innervate the intrinsic eye muscles that enable pupillary constriction and accommodation (ability to focus on near objects as in reading).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Optic nerve The Oculomotor nerve lies between the superior cerebellar artery and the posterior cerebral artery. Option: C. Abducens nerve The Oculomotor nerve lies between the superior cerebellar artery and the posterior cerebral artery. Option: D. Trigeminal nerve The Oculomotor nerve lies between the superior cerebellar artery and the posterior cerebral artery.</p>\n<p><strong>Extraedge:</strong></p><p>The oculomotor nerve is derived from the basal plate of the embryonic midbrain.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the arrow marked vessel in the given image.", "options": [{"label": "A", "text": "Posterior Cerebral Arteries", "correct": false}, {"label": "B", "text": "Middle cerebral artery", "correct": false}, {"label": "C", "text": "Posterior communicating artery", "correct": true}, {"label": "D", "text": "Anterior cerebral artery", "correct": false}], "correct_answer": "C. Posterior communicating artery", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391814988-QTDA054004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior communicating artery In the image it can be seen originating from ICA and joining with the posterior cerebral artery contributing to the circle of Willis and connecting the anterior and posterior circulation. Circle of willis</p>\n<p><strong>Highyeild:</strong></p><p>The circle of Willis ( also called Willis' circle, loop of Willis, cerebral arterial circle, and Willis polygon) is a circulatory anastomosis that supplies blood to the brain and surrounding structures in humans. The circle of Willis is a part of the cerebral circulation and is composed of the following arteries: Anterior cerebral artery (left and right) Anterior communicating artery Internal carotid artery (left and right) Posterior cerebral artery (left and right) Posterior communicating artery (left and right)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Posterior Cerebral Arteries Option: B. Middle cerebral artery Option: D. Anterior cerebral artery In the image it can be seen originating from ICA and joining with the posterior cerebral artery contributing to the circle of Willis and connecting the anterior and posterior circulation, therefore Option A,B and D all are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The middle cerebral arteries, supplying the brain, are not considered part of the circle of Willis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Occlusion of posterior cerebral artery supplying visual cortex results in:", "options": [{"label": "A", "text": "Ipsilateral Homonymous Hemianopia", "correct": false}, {"label": "B", "text": "Contralateral homonymous hemianopia", "correct": false}, {"label": "C", "text": "Bitemporal Hemianopia", "correct": false}, {"label": "D", "text": "Contralateral homonymous hemianopia with macular sparing", "correct": true}], "correct_answer": "D. Contralateral homonymous hemianopia with macular sparing", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Contralateral homonymous hemianopia with macular sparing Sparing of the macula in thrombosis of posterior cerebral artery: Macula is represented at the occipital pole. It is supplied by branches of the middle cerebral artery or by anastomosis between the middle and posterior cerebral arteries. So thrombosis of the posterior cerebral artery does not harm the macula. A right occipital lobe infarction causes a left homonymous hemianopia with macular sparing.</p>\n<p><strong>Highyeild:</strong></p><p>Field defects associated with lesion of visual pathway Field defects associated with lesion of visual pathway. (1) Blindness of left eye; (2) Bitemporal hemianopia; (3) Left nasal hemianopia; (4) Right homonymous hemianopia with macular involvement; (5) Right homonymous hemianopia; (6) Right homonymous hemianopia with macular sparing</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Ipsilateral Homonymous Hemianopia A lesion in the left optic tract will cause right-sided homonymous hemianopsia, while a lesion in the right optic tract will cause left-sided homonymous hemianopsia. Homonymous hemianopsia (or homonymous hemianopia, HH) is a field loss deficit in the same halves of the visual field of each eye. This condition most commonly results from stroke for adults, or tumors/lesions for patients under the age of 18. Option: B. Contralateral homonymous hemianopia The optic tract represents the first stage in the visual pathway in which visual information is transferred in a homonymous nature. The Main characteristic feature of lesions involving the whole optic tract is homonymous hemianopsia. A lesion in the left optic tract will cause right-sided homonymous hemianopsia, while a lesion in the right optic tract will cause left-sided homonymous hemianopsia. Option: C. Bitemporal Hemianopia Bitemporal hemianopsia is the medical description of a type of partial blindness where vision is missing in the outer half of both the right and left visual fields. It is usually associated with lesions of the optic chiasm, the area where the optic nerves from the right and left eyes cross near the pituitary gland.</p>\n<p><strong>Extraedge:</strong></p><p>Level of Lesion location and associated visual field defect</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A major supply of medial surface of the cerebral hemisphere:", "options": [{"label": "A", "text": "Anterior Cerebral Artery", "correct": true}, {"label": "B", "text": "Posterior cerebral artery", "correct": false}, {"label": "C", "text": "Middle cerebral artery", "correct": false}, {"label": "D", "text": "Posterior inferior cerebral artery", "correct": false}], "correct_answer": "A. Anterior Cerebral Artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior Cerebral Artery The anterior cerebral artery ( ACA ) is one of a pair of cerebral arteries that supply oxygenated blood to most midline portions of the frontal lobes and superior medial parietal lobes of the brain. The two anterior cerebral arteries arise from the internal carotid artery and are part of the circle of Willis. The left and right anterior cerebral arteries are connected by the anterior communicating artery. Anterior cerebral artery Medial surface of right cerebral hemisphere with anterior cerebral artery.</p>\n<p><strong>Highyeild:</strong></p><p>Anterior cerebral artery syndrome refers to symptoms that follow a stroke occurring in the area normally supplied by one of the arteries. It is characterized by weakness and sensory loss in the lower leg and foot opposite to the lesion and behavioral changes.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Posterior cerebral artery The posterior cerebral artery ( PCA ) is one of a pair of cerebral arteries that supply oxygenated blood to the occipital lobe, part of the back of the human brain. The two arteries originate from the distal end of the basilar artery, where it bifurcates into the left and right posterior cerebral arteries. These anastomose with the middle cerebral arteries and internal carotid arteries via the posterior communicating arteries. Option: C. Middle cerebral artery The middle cerebral artery ( MCA ) is one of the three major paired cerebral arteries that supply blood to the cerebrum. The MCA arises from the internal carotid artery and continues into the lateral sulcus where it then branches and projects to many parts of the lateral cerebral cortex. It also supplies blood to the anterior temporal lobes and the insular cortices. Option: D. Posterior inferior cerebral artery The posterior inferior cerebellar artery ( PICA ) is the largest branch of the vertebral artery. It is one of the three main arteries that supply blood to the cerebellum, a part of the brain. Blockage of the posterior inferior cerebellar artery can result in a type of stroke called lateral medullary syndrome.</p>\n<p><strong>Extraedge:</strong></p><p>The anterior cerebral artery supplies a part of the frontal lobe, specifically its medial surface and the upper border. It also supplies the front four–fifths of the corpus callosum, and provides blood to deep structures such as the anterior limb of the internal capsule, part of the caudate nucleus, and the anterior part of the globus pallidus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following are branches of intercavernous part of internal carotid artery, except:", "options": [{"label": "A", "text": "Hypophyseal Branches", "correct": false}, {"label": "B", "text": "Ophthalmic artery", "correct": true}, {"label": "C", "text": "Branch to trigeminal ganglion", "correct": false}, {"label": "D", "text": "Meningeal artery", "correct": false}], "correct_answer": "B. Ophthalmic artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ophthalmic artery Ophthalmic artery is a branch of the cerebral part of the internal carotid artery.</p>\n<p><strong>Highyeild:</strong></p><p>Internal carotid artery For the convenience of description, the course of the artery is divided into 4 parts: Cervical Part: No branches arise from the internal carotid artery in the neck. Petrous Part Branches: Caroticotympanic branches, The pterygoid branch (small and inconstant) The Cavernous part runs in the cavernous sinus. Cerebral part lies at the base of the skull and gives ophthalmic, anterior cerebral, middle cerebral, posterior communicating, and anterior choroidal arteries.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Hypophyseal Branches The superior hypophyseal artery is an artery supplying the pars tuberalis, the infundibulum of the pituitary gland, and the median eminence. It is a branch of the ophthalmic part of the internal carotid artery. The inferior hypophyseal artery is an artery in the head. It is a branch of the cavernous carotid artery, itself from the internal carotid artery. It supplies the posterior pituitary of the pituitary gland. Option: C. Branch to trigeminal ganglion The artery to trigeminal nerve ganglion (located in the foramen ovale) arises from the extracranial segment of the middle meningeal artery prior to entry into the foramen spinosum. Option: D. Meningeal artery The middle meningeal artery most often branches off the maxillary artery and courses into the middle cranial fossa via the foramen spinosum. The middle meningeal artery provides blood to the dura mater through and through its branching arteries and also supplies the periosteum of the inner aspects of the cranial bones.</p>\n<p><strong>Extraedge:</strong></p><p>The internal carotid artery is a terminal branch of the common carotid artery; it arises around the level of the fourth cervical vertebra when the common carotid bifurcates into this artery and its more superficial counterpart, the external carotid artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Blood supply of putamen includes all, except", "options": [{"label": "A", "text": "Medial Striate Arteries", "correct": false}, {"label": "B", "text": "Lateral striate arteries", "correct": false}, {"label": "C", "text": "Anterior choroidal artery", "correct": false}, {"label": "D", "text": "Posterior communicating artery", "correct": true}], "correct_answer": "D. Posterior communicating artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior communicating artery Basal ganglia components (including putamen) are supplied by the striate (medial and lateral) arteries, which are branches from the roots of the anterior and middle cerebral arteries. The posteroinferior part of the lentiform complex is supplied by the thalamostriate branches of the posterior cerebral artery. Additional contributions are from the anterior choroidal artery (branch of the internal carotid artery).</p>\n<p><strong>Highyeild:</strong></p><p>The main function of the posterior communicating artery is to provide an alternative route to the brain blood supply in case there is a blockage of the internal carotid or vertebral arteries. Besides this, the posterior communicating artery contributes to the blood supply of the internal capsule, parts of the diencephalon, and third ventricle via its posterolateral central branches.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Medial Striate Arteries Basal ganglia components (including putamen) are supplied by the striate (medial and lateral) arteries, which are branches from the roots of the anterior and middle cerebral arteries. Option: B. Lateral striate arteries Basal ganglia components (including putamen) are supplied by the striate (medial and lateral) arteries, which are branches from the roots of the anterior and middle cerebral arteries. Option: C. Anterior choroidal artery Additional contributions to the arterial supply of putamen are from the anterior choroidal artery (branch of the internal carotid artery).</p>\n<p><strong>Extraedge:</strong></p><p>Aneurysms of the posterior communicating artery are the third most common circle of Willis aneurysms (the most common are anterior communicating artery aneurysms) and can lead to oculomotor nerve palsy.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 18 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A patient was rushed to ER, with head injury, after getting hit by a bus, and falling on his face onto the road. Frontal and nasal bones, along with the medial side of the orbital rim of the right eye are fractured, and there is profuse bleeding from that site. Which two blood vessels form anastomosis at the medial angle of eye, injury to which, resulted in profuse bleeding in our patient?", "options": [{"label": "A", "text": "Supraorbital artery and superficial temporal artery", "correct": false}, {"label": "B", "text": "Dorsal nasal artery and angular artery", "correct": true}, {"label": "C", "text": "Anterior ethmoidal artery and superior labial artery", "correct": false}, {"label": "D", "text": "Superior labial and supraorbital artery", "correct": false}], "correct_answer": "B. Dorsal nasal artery and angular artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Dorsal nasal artery and angular artery Facial part of the facial artery gives 4 branches while ascending through the face. They are inferior labial artery, superior labial artery, lateral nasal artery and angular artery. Angular artery is not an end artery . It ascends up to the medial angle of the eye, where it anastomoses with the dorsal nasal artery. Dorsal nasal artery is a branch of ophthalmic artery , which in turn is a branch of internal carotid artery. So, this anastomosis at the medial angle of the eye is between the branches of the external carotid artery and internal carotid artery. The other piles of anastomoses between external and internal carotid arteries include superior orbital artery(ICA) and superficial temporal artery(ECA); ophthalmic artery(ICA) and middle meningeal artery(ECA); dorsal nasal artery(ICA) and nasal branches of facial artery(ECA); anterior and posterior ethmoidal arteries(ICA) and sphenopalatine artery(ECA) etc. The superior labial artery and superficial temporal artery are not located at the medial angle of the eye. Hence, cannot be involved in bleeding from these sites.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 15 year old girl was brought to the ER, with fever, associated with severe headache, for 2 days. She is also complaining of blurred vision and double vision. She also says that her eye movements are very painful. On examination, there is periorbital swelling, slight ptosis of the left eye. She is a known case of chronic sinusitis. Which vein among the below connects the facial vein to cavernous sinus?", "options": [{"label": "A", "text": "Angular Vein", "correct": false}, {"label": "B", "text": "Superior ophthalmic vein", "correct": false}, {"label": "C", "text": "Deep facial vein", "correct": true}, {"label": "D", "text": "Superficial temporal vein", "correct": false}], "correct_answer": "C. Deep facial vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deep facial vein Facial vein --> deep facial vein --> pterygoid venous plexus --> emissary vein --> cavernous sinus Based on the clinical presentation, the diagnosis is cavernous sinus thrombosis. Infections from the face can spread to the cavernous sinus in a retrograde direction and cause thrombosis of the cavernous sinus, through the facial artery. This occurs when there is any infection in the dangerous area of the face, i.e., infection in the upper lip and lower part of the The facial veins are devoid of valves, making an uninterrupted passage of blood to cavernous sinus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 32-year-old unconscious man is admitted to the emergency department after being hit by a car followed by a fall with head striking on the ground. A CT scan examination reveals a fractured pterion and an epidural hematoma. Which of the following arteries are most likely to be injured?", "options": [{"label": "A", "text": "External Carotid", "correct": false}, {"label": "B", "text": "Superficial temporal", "correct": false}, {"label": "C", "text": "Deep temporal", "correct": false}, {"label": "D", "text": "Middle meningeal", "correct": true}], "correct_answer": "D. Middle meningeal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Middle meningeal The middle meningeal artery is a branch of the maxillary artery and courses between the dura mater and skull close to the area of the pterion. Any fracture or impact trauma to this location typically results in a laceration of the middle meningeal artery resulting in an epidural hematoma.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A and B. The external carotid artery ends behind the mandible by dividing into the maxillary and the superficial temporal arteries, and neither of these arteries directly affects the meninges of the brain. Option: C. The deep temporal arteries do not penetrate the bony skull and thus would not contribute to an epidural hematoma.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An 18-year-old man was brought to the emergency department because of severe epistaxis (nosebleed) from the nasal septum. This area, known as Kiesselbach's (or Little's) area, involves mostly anastomoses between which of the following arteries?", "options": [{"label": "A", "text": "Ascending palatine and ascending pharyngeal", "correct": false}, {"label": "B", "text": "Posterior superior alveolar and accessory meningeal", "correct": false}, {"label": "C", "text": "Lateral branches of posterior ethmoidal and middle meningeal", "correct": false}, {"label": "D", "text": "Septal branches of the sphenopalatine and superior labial", "correct": true}], "correct_answer": "D. Septal branches of the sphenopalatine and superior labial", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Septal branches of the sphenopalatine and superior labial Kiesselbach’s plexus (also called Little’s area) is an anastomosis of four arteries on the anterior nasal septum. The four arteries are the anterior ethmoidal artery, sphenopalatine artery, superior labial artery, and greater palatine artery. However , the two largest contributors are the septal branches of the Sphenopalatine . (from the maxillary artery) and superior labial arteries (branches of the facial artery, which is a branch of the external carotid artery).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options A, B, C: The ascending palatine, ascending pharyngeal, Posterior superior alveolar, accessory meningeal, Lateral branches of posterior ethmoidal and middle meningeal. Do not contribute to the making of Kiesselbach’s plexus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 16-year-old boy is admitted to the hospital with fever, a confused mental state, and drowsiness. During physical examination it is noted that the boy suffers from severe acne. Radiological examination reveals cavernous sinus thrombosis. Which of the following routes of entry to the cavernous sinus would most likely be responsible for the infection and thrombosis?", "options": [{"label": "A", "text": "Carotid Artery", "correct": false}, {"label": "B", "text": "Mastoid emissary vein", "correct": false}, {"label": "C", "text": "Middle meningeal artery", "correct": false}, {"label": "D", "text": "Ophthalmic vein", "correct": true}], "correct_answer": "D. Ophthalmic vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ophthalmic vein Cavernous sinus thrombosis can often result from squeezing pimples or other infectious processes around the face's danger area , including the face area directly surrounding the nose. This physical pressure can potentially move infectious agents from the pimple into the ophthalmic vein, which then carries it to the cavernous sinus. The pterygoid venous plexus and ophthalmic vein communicate with the cavernous sinus and therefore offer a route of travel for the spread of infection. Still, the path provided by the superior ophthalmic vein is a more direct route. Additionally, the superior ophthalmic vein receives blood supply from the supraorbital, supratrochlear, and angular veins that supply The area around the nose and lower forehead. (Venous blood in the head can flow in either direction because these veins do not possess valves. )</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options: A, C. The middle meningeal artery courses between the dura and periosteum, whereas the carotid artery, specifically the ICA, traverses through the cavernous sinus, providing origin to the ophthalmic artery. As with the middle meningeal artery, the carotid artery would not offer a communication route between the area of infection and the cavernous sinus. Option: B. The emissary veins communicate between the venous sinuses and the veins of the scalp and would, therefore1, not1 be involved in the spread of infection between the nose and cavernous sinus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old woman is admitted to the hospital with a severe headache. The patient is diagnosed with hypertension and arrhythmias. To reduce the patient's blood pressure, massage is initiated at a pressure point located deep to the anterior border of the sternocleidomastoid muscle at the level of the superior border of the thyroid cartilage. Which of the following structures is targeted by the massage?", "options": [{"label": "A", "text": "Carotid Sinus", "correct": true}, {"label": "B", "text": "Carotid body", "correct": false}, {"label": "C", "text": "Thyroid gland", "correct": false}, {"label": "D", "text": "Parathyroid gland", "correct": false}], "correct_answer": "A. Carotid Sinus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Carotid Sinus The carotid sinus is a baroreceptor that can be targeted for carotid massage to decrease blood pressure. The carotid sinus receptors are sensitive to changes in pressure. For this reason, sustained compression of the carotid sinuses can lead to unconsciousness or death as the heart rate is reflexively reduced.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. The carotid body is a chemoreceptor, responsive to the balance of oxygen and carbon dioxide. Options: C, D. Neither the thyroid gland nor the parathyroid gland has anything to do with acute control of blood pressure due to mechanical stimuli.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The cephalic vein drains into:", "options": [{"label": "A", "text": "Brachial Vein", "correct": false}, {"label": "B", "text": "Subclavian Vein", "correct": false}, {"label": "C", "text": "Axillary Vein", "correct": true}, {"label": "D", "text": "IVC", "correct": false}], "correct_answer": "C. Axillary Vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Axillary Vein The cephalic vein pierces the clavipectoral fascia and joins the axillary vein. Cephalic Vein Option: Axillary vein- The cephalic vein, along with the basilic vein, is one of the primary superficial veins that drain the upper limb. It courses through both the forearm and arm and terminates by draining into the axillary vein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Brachial veins are venae comitantes of the brachial artery in the arm proper. Because they are deep in the muscle, they are considered deep veins. Their course is that of the brachial artery (in reverse): they begin where radial veins and ulnar veins join (corresponding to the bifurcation of the brachial artery). They end at the inferior border of the teres major muscle. At this point, the brachial veins join the basilic vein to form the axillary vein. Option: B. Each subclavian vein is a continuation of the axillary vein and runs from the outer border of the first rib to the medial border of the anterior scalene muscle. From here it joins with the internal jugular vein to form the brachiocephalic vein (also known as \"innominate vein\"). Option: D. IVC- The IVC is a large blood vessel responsible for transporting deoxygenated blood from the lower extremities and abdomen back to the right atrium of the heart.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Anastomosis of the subscapular artery is formed by all except:", "options": [{"label": "A", "text": "Transverse Cervical Artery", "correct": false}, {"label": "B", "text": "Suprascapular Artery", "correct": false}, {"label": "C", "text": "1st Part of Subclavian Artery", "correct": false}, {"label": "D", "text": "2nd Part of Axillary Artery", "correct": true}], "correct_answer": "D. 2nd Part of Axillary Artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2nd Part of Axillary Artery Subscapular artery anastomosis with transverse cervical and suprascapular arteries, mainly. The transverse cervical artery and suprascapular artery are branches of the first part of the subclavian artery.</p>\n<p><strong>Highyeild:</strong></p><p>Anastomosis Around the Body of the Scapula Anastomosis Around the Body of the Scapula The anastomosis occurs in the three fossae—subscapular, supraspinous, and infraspinous. It is formed by: The suprascapular artery is a branch of the thyrocervical trunk. The deep branch of the transverse cervical artery is another branch of the thyrocervical trunk. The circumflex scapular artery is a branch of the subscapular artery that arises from the third part of the axillary artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A . Transverse Cervical Artery Option: B. Suprascapular artery Option: C. 1st part of the subclavian artery</p>\n<p><strong>Extraedge:</strong></p><p>Anastomosis Over the Acromion Process It is formed by: The acromial branch of the thoracoacromial artery (2nd part of axillary). The acromial branch of the suprascapular artery (1st part of subclavian). The acromial branch of the posterior circumflex humeral artery (3rd part of axillary).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Occlusion occurs at 2nd part of the axillary artery; blood flow is maintained by anastomosis between:", "options": [{"label": "A", "text": "Anterior and posterior circumflex humeral artery", "correct": false}, {"label": "B", "text": "Circumflex scapular and posterior circumflex humeral", "correct": false}, {"label": "C", "text": "Deep branch of the transverse cervical artery and subscapular artery", "correct": true}, {"label": "D", "text": "Anterior circumflex and subscapular artery", "correct": false}], "correct_answer": "C. Deep branch of the transverse cervical artery and subscapular artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deep branch of the transverse cervical artery and subscapular artery Anastomosis Around the Body of the Scapula Option: C. Deep branch o f the transverse cervical artery and subscapular artery The anastomosis occurs in the three fossae—subscapular, supraspinous, and infraspinous. It is formed by: The suprascapular artery is a branch of the thyrocervical trunk. The deep branch of the transverse cervical artery is another branch of the thyrocervical trunk. The circumflex scapular artery is a branch of the subscapular artery that arises from the third part of the axillary artery. Note that it is the anastomosis between branches of the first part of the subclavian artery and the branches of the third part of the axillary artery. These arteries are also anastomose with intercostal arteries.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Anterior and posterior circumflex humeral artery The anterior circumflex hume ral artery anastomoses with the posterior humeral circumflex artery around the surgical neck of the humerus. Option B. Circumflex scapular and posterior circumflex humeral Circumflex scapular artery anastomosis with Suprascapular artery, a branch of the thyrocervical trunk, and deep branch of the transverse cervical artery, another branch of the thyrocervical trunk. Option D. Anterior circumflex and subscapular artery The anterior circumflex humera l artery anastomoses with the posterior humeral circumflex artery around the surgical neck of the humerus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The posterior interosseous artery is a branch of:", "options": [{"label": "A", "text": "Radial Artery", "correct": false}, {"label": "B", "text": "Ulnar Artery", "correct": true}, {"label": "C", "text": "Brachial Artery", "correct": false}, {"label": "D", "text": "Axillary Artery", "correct": false}], "correct_answer": "B. Ulnar Artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ulnar Artery The common interosseous artery (about 1 cm long) arises from the ulnar artery, just below the radial tuberosity. It passes backward to reach the upper border of the interosseous membrane and ends by dividing into the anterior and posterior interosseous arteries. Anterior and Posterior interosseous artery</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Radial Artery: Branches of Radial artery In the forearm Radial recurrent artery Palmar carpal branch of radial artery Superficial palmar branch of the radial artery At the wrist Dorsal carpal branch of radial artery In the hand Princeps pollicis artery Radialis indicis Deep palmar arch Option: C. Brachial artery: Branches of Brachial artery Profunda brachii Nutrient artery of the humerus Superior ulnar collateral artery Middle ulnar collateral artery Inferior ulnar collateral artery Deltoid artery Radial artery Ulnar artery Option: D. Axillary artery : Branches of Axillary artery The first part (1 branch) Superior thoracic artery (Supreme thoracic artery) The second part (2 branches) Thoraco-acromial artery Lateral thoracic artery The third part (3 branches) Subscapular artery The anterior humeral circumflex artery Posterior humeral circumflex artery</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The recurrent interosseous artery is a branch of the?", "options": [{"label": "A", "text": "Anterior Interosseous Artery", "correct": false}, {"label": "B", "text": "Posterior interosseous artery", "correct": true}, {"label": "C", "text": "Common interosseous artery", "correct": false}, {"label": "D", "text": "Radial recurrent artery", "correct": false}], "correct_answer": "B. Posterior interosseous artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior interosseous artery The posterior interosseous artery gives off an interosseous recurrent branch that runs upwards and takes part in the anastomosis on the back of the lateral epicondyle of the humerus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: C. Common interosseous artery The common interosseous artery (about 1 cm long) arises from the ulnar artery, just below the radial tuberosity. It passes backward to reach the upper border of the interosseous membrane and ends by dividing into the anterior and posterior interosseous arteries. Option: D. Radial recurrent artery The radial recurrent artery arises from the radial artery immediately below the elbow. It ascends between the branches of the radial nerve, lying on the supinator muscle and then between the brachioradialis muscle and the brachialis muscle, supplying these muscles and the elbow-joint, and anastomosing with the terminal part of the profunda brachii.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A deep palmar arch is formed by:", "options": [{"label": "A", "text": "Mainly radial artery and partly ulnar artery", "correct": true}, {"label": "B", "text": "Mainly ulnar artery and partly Radial artery", "correct": false}, {"label": "C", "text": "Ulnar artery and radial artery equally", "correct": false}, {"label": "D", "text": "A and B", "correct": false}], "correct_answer": "A. Mainly radial artery and partly ulnar artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Mainly radial artery and partly ulnar artery Deep palmar arch The deep palmar arch is formed mainly by the terminal part of the radial artery and is completed medially at the base of the fifth metacarpal bone by the deep palmar branch of the ulnar artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Mainly ulnar artery and partly Radial artery Option: C. Ulnar artery and radial artery equally Option: D. A and B</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Anastomosis around the shoulder is between branches of:", "options": [{"label": "A", "text": "1st part of the subclavian and 1st part of the axillary artery.", "correct": false}, {"label": "B", "text": "1st part of subclavian and 3rd part of the axillary artery.", "correct": true}, {"label": "C", "text": "3rd part of subclavian and 2nd part of the axillary artery.", "correct": false}, {"label": "D", "text": "3rd part of the subclavian and 3rd part of the axillary artery.", "correct": false}], "correct_answer": "B. 1st part of subclavian and 3rd part of the axillary artery.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1st part of subclavian and 3rd part of the axillary artery. Shoulder anastomosis occurs between branches of the 1st part of the subclavian artery and 3rd part of the axillary artery. Two sites of scapular anastomosis: Around the body of the scapula: Suprascapular artery (branch of the thyrocervical trunk from the first part of the subclavian artery Circumflex scapular artery (branch of the subscapular artery from the 3rd part of the axillary artery Deep branch of the transverse cervical artery (branch of the thyrocervical trunk) Over the acromion process. Acromial branch of the thoracoacromial artery Acromial branch of the suprascapular artery Acromial branch of the posterior circumflex humeral artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options A, C, and D. are Incorrect because Shoulder anastomosis occurs between branches of the 1st part of the subclavian artery and the 3rd part of the axillary artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which branch of the subclavian artery directly contributes to scapular anastomosis:", "options": [{"label": "A", "text": "Vertebral", "correct": false}, {"label": "B", "text": "Internal Thoracic", "correct": false}, {"label": "C", "text": "Thyrocervical Trunk", "correct": false}, {"label": "D", "text": "Dorsal Scapular", "correct": true}], "correct_answer": "D. Dorsal Scapular", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Dorsal Scapular The dorsal s capular artery is a direct branch from the subclavian artery participating in scapular anastomosis. It anastomoses with the suprascapular and subscapular arteries and with posterior branches of some posterior intercostal arteries. The dorsal scapular artery is a branch of either the transverse cervical artery (from the thyrocervical trunk of the first part of the subclavian artery) or an independent branch from the third (or less commonly second) part of the subclavian artery. It accompanies the dorsal scapular nerve , coursing deep to the levator scapulae and rhomboid muscles, supplying both and contributing to the scapular arterial anastomosis. Option: C. Thyrocervical Trunk. Thyrocervical trunks do not participate in scapular anastomosis directly. It gives branches (like the Suprascapular artery and sometimes the dorsal scapular artery) to contribute to scapular anastomosis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A and B are incorrect answers because they do not take part in scapular anastomosis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Artery forming anastomosis around the surgical neck of the humerus is a branch of:", "options": [{"label": "A", "text": "1st part of axillary artery", "correct": false}, {"label": "B", "text": "2nd part of axillary artery", "correct": false}, {"label": "C", "text": "3rd part of axillary artery", "correct": true}, {"label": "D", "text": "Subclavian artery", "correct": false}], "correct_answer": "C. 3rd part of axillary artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>3rd part of axillary artery Arteries forming anastomosis around the surgical neckof the humerus are Anterior circumflex humeral arteries Posterior circumflex humeral arteries Both are branches of the 3rd part of the axillary artery</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options A, B, and D do not contribute to forming anastomosis around the surgical neck of the humerus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following statements are true regarding anterior axillary lymph nodes except:", "options": [{"label": "A", "text": "Present on the anterior wall of the axilla on the pectoral muscle", "correct": false}, {"label": "B", "text": "Present along the lateral thoracic vein", "correct": false}, {"label": "C", "text": "Drains into central axillary lymph nodes", "correct": false}, {"label": "D", "text": "Drains the medial aspect of the mammary gland", "correct": true}], "correct_answer": "D. Drains the medial aspect of the mammary gland", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Drains the medial aspect of the mammary gland Drains the medial aspect of the mammary gland The medial aspect of the mammary gland drains into internal mammary LNs Options A, B, and C are correct statements. Anterior axillary/pectoral lymph nodes are present along the lateral thoracic vein on the anterior wall of the axilla on the pectoral muscle This drains the lateral aspect of the mammary gland. And finally drains into central axillary lymph nodes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In the subclavian artery block at the outer border of the first rib, all of the following arteries help in maintaining the circulation of the upper limb except:", "options": [{"label": "A", "text": "Thyrocervical Trunk", "correct": false}, {"label": "B", "text": "Suprascapular", "correct": false}, {"label": "C", "text": "Subscapular", "correct": false}, {"label": "D", "text": "Superior Thoracic", "correct": true}], "correct_answer": "D. Superior Thoracic", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior Thoracic Scapular anastomosis maintains circulation to the upper limb in this clinical situation, which doesn't involve superior thoracic arteries. Shoulder anastomosis occurs between branches of the 1st part of the subclavian artery and 3rd part of the axillary artery. The superior thoracic artery is the branch of 1st part of the axillary artery , so do not contribute to forming Scapular anastomosis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Thyrocervical Trunk is the branch of 1st part of the subclavian artery, so it contributes to the scapular anastomosis. Option: B. Suprascapular artery is the branch of the thyrocervical trunk, so it contributes to the scapular anastomosis. Option: C. Subscapular artery is the branch of the 3rd part of the axillary artery, so it contributes to the scapular anastomosis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The mammary gland is supplied by:", "options": [{"label": "A", "text": "Subscapular Artery", "correct": true}, {"label": "B", "text": "Musculophrenic Artery", "correct": false}, {"label": "C", "text": "Inferior epigastric Artery", "correct": false}, {"label": "D", "text": "Superior epigastric Artery", "correct": false}], "correct_answer": "A. Subscapular Artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Subscapular Artery Arterial supply of breast Branches of axillary artery Superior thoracic artery Thoracoacromial artery Lateral thoracic artery Subscapular artery Internal thoracic (mammary artery) via the medial mammary arteries. Perforating branches of second, third, and fourth posterior intercostal arteries.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Musculophrenic artery gives branches to the lower part of the pericardium, and others which run backward to the diaphragm , and downward to the abdominal muscles. Option: C. Inferior epigastric artery traverses the arcuate line of the rectus sheath to enter the rectus sheath, then anastomoses with the superior epigastric artery within the rectus sheath. Option: D. Superior epigastric artery is a terminal branch of the internal thoracic artery that provides arterial supply to the abdominal wall, and upper rectus abdominis muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 19-year-old boy fell from the motorbike on his shoulder. The doctor diagnosed him with a case of Erb’s paralysis. The following signs and symptoms will be observed:", "options": [{"label": "A", "text": "Loss of abduction at the shoulder joint", "correct": false}, {"label": "B", "text": "Loss of lateral rotation", "correct": false}, {"label": "C", "text": "Loss of pronation at radioulnar joint", "correct": true}, {"label": "D", "text": "Loss of flexion at the elbow joint", "correct": false}], "correct_answer": "C. Loss of pronation at radioulnar joint", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Loss of pronation at radioulnar joint Pronation at the radioulnar joint is carried by the pronator teres and pronator quadratus muscle, supplied by the median nerve with root value C-7 mainly. Hence there will be no loss of pronation in Erb’s paralysis. In Erb’ s palsy, t here is a weakness of supination due to paralyzed biceps brachii secondary to the injury o f the musculocutaneous nerve (C-5 and C-6). Option: A, B, and D all are lost in Erb’s palsy.</p>\n<p><strong>Highyeild:</strong></p><p>The following movements and sensations are lost in Erb’s palsy: Abduction and lateral rotation of the arm at the shoulder Flexion and supination of the forearm. Biceps and supinator jerks are lost. Sensations are lost over a small area over the lower part of the deltoid.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 29-year-old man comes to the emergency room with a stab wound, cannot raise his arm horizontally, and exhibits a condition known as “winged scapula”. Which of the following structures of the brachial plexus would most likely be damaged?", "options": [{"label": "A", "text": "Medial Cord", "correct": false}, {"label": "B", "text": "Posterior Cord", "correct": false}, {"label": "C", "text": "Lower Trunk", "correct": false}, {"label": "D", "text": "Roots", "correct": true}], "correct_answer": "D. Roots", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Roots Winged scapula is caused by paralysis of the serratus anterior muscle that results from damage to the long thoracic nerve , which arises from the roots of the brachial plexus (C5-C7). Option: A, B, and C are not the correct answer because the long thoracic nerve is a branch of the root of the brachial plexus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A fall on the shoulder resulted in the arm being held in a medially rotated position and the forearm pronated. The following facts concerning this patient are correct, EXCEPT:", "options": [{"label": "A", "text": "The injury was at Erb’s point", "correct": false}, {"label": "B", "text": "A lesion of C5 and C6 was present", "correct": false}, {"label": "C", "text": "The median and ulnar nerves were affected", "correct": true}, {"label": "D", "text": "Supraspinatus, infraspinatus, and biceps brachii were paralyzed", "correct": false}], "correct_answer": "C. The median and ulnar nerves were affected", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The median and ulnar nerves were affected In the given case, the arm is held in a medially rotated position, and forearm pronated. This points towards a case of Erb’s paralysis (C5, C6 Nerve Injury). Only the Ulnar nerve is involved in Klumpke’s Paralysis. Deformity: Policeman/porter/waiter’s tip hand Disability: Loss of the following movements: Abduction and lateral rotation of the arm at the shoulder Biceps with supinator jerk lost Sensory loss over a small area of the deltoid</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The injury was at Erb’s point Site of injury: The region of the upper trunk of the brachial plexus is called Erb’s point. Six nerves meet here. Injury to the upper trunk causes Erb’s paralysis. Option: B. A lesion of C5 and C6 was present: This is a case of Erb’s paralysis (C5, C6 Nerve Injury)</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 17-year-old boy fell from his motorcycle and complains of numbness on the lateral aspect of his arm. Examination reveals that the axillary nerve is severed. Which of the following types of axons is most likely to be spared?", "options": [{"label": "A", "text": "Postganglionic Sympathetic Axons", "correct": false}, {"label": "B", "text": "Somatic afferent axons", "correct": false}, {"label": "C", "text": "Preganglionic sympathetic axons", "correct": true}, {"label": "D", "text": "General somatic efferent axons", "correct": false}], "correct_answer": "C. Preganglionic sympathetic axons", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Preganglionic sympathetic axons Preganglionic sympathetic axons: The axillary nerve contains no preganglionic sympathetic general visceral efferent(GVE) fibers, but it contains postganglionic sympathetic GVE fibers</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: D. General somatic efferent axons: The axillary nerve also contains GSA, GSE, and general visceral afferent (GVA) fibers.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 35-year-old patient has small but painful tumors under the nail of the little finger. Which of the following nerves would have to be anesthetized for painless removal of the tumor?", "options": [{"label": "A", "text": "Superficial Radial", "correct": false}, {"label": "B", "text": "Common palmar digital branch of the median nerve", "correct": false}, {"label": "C", "text": "Common palmar digital branch of ulnar nerve", "correct": true}, {"label": "D", "text": "Deep Radial", "correct": false}], "correct_answer": "C. Common palmar digital branch of ulnar nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Common palmar digital branch of ulnar nerve The common palmar digital branch of the ulnar nerve has to be anesthetized for this surgery. The common palmar digital nerves of the ulnar nerve are nerves of the hand. The nerve branches off the superficial branch of the ulnar nerve and runs toward the cleft between the ring and little fingers The common palmar digital branch of the radial nerve supplies the radial(lateral) dorsum of the hand and radial two digits over the proximal phalanx</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Superficial Radial The superficial branch of the radial nerve passes beneath the tendon of the Brachioradialis, and, piercing the deep fascia, divides into two branches: lateral and medial. Option: B. Common palmar digital branch of median nerve supplies Lateral aspect of Palmer's hand The palmar aspect of the second and 3rd finger The lateral part of the 4th digit Option: D. Deep radial nerve supplies extensor carpi radialis brevis and supinator muscles.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 37-year-old female has a fracture of the clavicle. The junction of the inner and middle third of the bone exhibits overriding of medial and lateral fragments. The arm is rotated medially, but it is not rotated laterally. Which of the following conditions is most likely to occur secondary to the fractured clavicle?", "options": [{"label": "A", "text": "A fatal hemorrhage from the brachiocephalic vein.", "correct": false}, {"label": "B", "text": "Thrombosis of the subclavian vein, causing an embolism in ascending aorta.", "correct": true}, {"label": "C", "text": "Thrombosis of the subclavian artery, causing an embolism in ascending aorta.", "correct": false}, {"label": "D", "text": "Damage to the upper trunk of the brachial plexus.", "correct": false}], "correct_answer": "B. Thrombosis of the subclavian vein, causing an embolism in ascending aorta.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thrombosis of the subclavian vein, causing an embolism in ascending aorta. The fractured clavicle may damage the subclavian vein, resulting in pulmonary embolism, cause thrombosis of the subclavian artery, resulting in embolism of the brachial artery; or damage the lower trunk o f the brachial plexus. The most common late vascular complication following a clavicular fracture is occlusion after compression of the subclavian vein between the fractured clavicle and the first rib. In these situations, sudden dyspnea, pleuritic chest pain, hemoptysis, syncope or shock, and tachypnea can indicate the presence of pulmonary embolism</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Branches of the brachial artery are all, except:", "options": [{"label": "A", "text": "Profunda Brachii", "correct": false}, {"label": "B", "text": "Superior ulnar collateral", "correct": false}, {"label": "C", "text": "Inferior ulnar collateral", "correct": false}, {"label": "D", "text": "Posterior circumflex humeral artery", "correct": true}], "correct_answer": "D. Posterior circumflex humeral artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior circumflex humeral artery The posterior circumflex humeral artery is a branch from the third part of the axillary artery. Axillary artery Branches</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 14-year-old boy falls on his outstretched hand and has a fracture of the scaphoid bone. The fracture is most likely accompanied by rupture of which of the following arteries?", "options": [{"label": "A", "text": "Brachial Artery", "correct": false}, {"label": "B", "text": "Ulnar Artery", "correct": false}, {"label": "C", "text": "Deep Palmar Arterial Arch", "correct": false}, {"label": "D", "text": "Radial Artery", "correct": true}], "correct_answer": "D. Radial Artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Radial Artery The scaphoid bone forms the floor of the anatomical snuffbox, through which the radial artery passes to enter the palm. The radial artery divides into the Principal Pollicis artery and the Deep palmar arch. Radial artery in Anatomical Snuff Box</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 17-year-old boy with a stab wound received multiple injuries on the upper part of his arm and required surgery. If the brachial artery were ligated at its origin, which of the following arteries would supply blood to the profunda brachii artery?", "options": [{"label": "A", "text": "Lateral Thoracic", "correct": false}, {"label": "B", "text": "Subscapular", "correct": false}, {"label": "C", "text": "Posterior humeral circumflex", "correct": true}, {"label": "D", "text": "Superior ulnar collateral", "correct": false}], "correct_answer": "C. Posterior humeral circumflex", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior humeral circumflex Posterior humeral circumflex anastomosis with Profunda brachii artery The posterior humeral circumflex artery anastomoses with an ascending branch of the profunda brachii artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B . Subscapular: The lateral thoracic and subscapular arteries do not anastomose with the profunda brachii artery. Option: D. Superior ulnar collateral: The superior ulnar collateral and radial recurrent arteries arise inferior to the origin of the profunda brachii artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient complains of having pain with repeated movements of his thumb (claudication). His physician performs Allen’s test and finds an insufficiency of the radial artery. Which of the following conditions would be a result of radial artery stenosis?", "options": [{"label": "A", "text": "A marked decrease in the blood flow in the superficial palmar arterial arch", "correct": false}, {"label": "B", "text": "Decreased pulsations in the artery passing superficial to the flexor retinaculum.", "correct": false}, {"label": "C", "text": "Ischemia of the entire extensor muscles of the forearm.", "correct": false}, {"label": "D", "text": "A marked decrease in the blood flow in the princeps pollicis artery.", "correct": true}], "correct_answer": "D. A marked decrease in the blood flow in the princeps pollicis artery.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A marked decrease in the blood flow in the princeps pollicis artery. The radial artery divides into the princeps pollicis artery and the deep palmar arterial arch. Thus, stenosis of the radial artery results in decreased blood flow in the princeps pollicis artery. Radial artery and Deep Palmar arch:</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. A marked decrease in the blood flow in the superficial palmar arterial arch Option B. Decreased pulsations in the artery passing superficial to the flexor retinaculum: Superficial palmar arterial arch is formed primarily by the ulnar artery, which passes superficial to the flexor retinaculum. Option: C. Ischemia of the entire extensor muscles of the forearm: The extensor compartment of the forearm receives blood from the posterior interosseous artery, which arises from the common interosseous branch of the ulnar artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 32 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Branches of the brachial artery are all, except:", "options": [{"label": "A", "text": "Profunda Brachii", "correct": false}, {"label": "B", "text": "Superior Ulnar Collateral", "correct": false}, {"label": "C", "text": "Inferior Ulnar Collateral", "correct": false}, {"label": "D", "text": "Posterior Circumflex Humeral Artery", "correct": true}], "correct_answer": "D. Posterior Circumflex Humeral Artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior Circumflex Humeral Artery The posterior circumflex humeral artery is a branch from the third part of the axillary artery. Profunda Brachii, Superior ulnar collateral, and Inferior ulnar collateral are branches of the brachial artery. Axillary artery Branches</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 14-year-old boy falls on his outstretched hand and has a fracture of the scaphoid bone. The fracture is most likely accompanied by rupture of which of the following arteries?", "options": [{"label": "A", "text": "Brachial Artery", "correct": false}, {"label": "B", "text": "Ulnar Artery", "correct": false}, {"label": "C", "text": "Deep Palmar Arterial Arch", "correct": false}, {"label": "D", "text": "Radial Artery", "correct": true}], "correct_answer": "D. Radial Artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Radial Artery The scaphoid bone forms the floor of the anatomical snuffbox, through which the radial artery passes to enter the palm. The radial artery divides into the Principal Pollicis artery and the Deep palmar arch. Radial artery in Anatomical Snuff Box</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 17-year-old boy with a stab wound received multiple injuries on the upper part of his arm and required surgery. If the brachial artery were ligated at its origin, which of the following arteries would supply blood to the profunda brachii artery?", "options": [{"label": "A", "text": "Lateral Thoracic", "correct": false}, {"label": "B", "text": "Subscapular", "correct": false}, {"label": "C", "text": "Posterior Humeral Circumflex", "correct": true}, {"label": "D", "text": "Superior Ulnar Collateral", "correct": false}], "correct_answer": "C. Posterior Humeral Circumflex", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior Humeral Circumflex Posterior humeral circumflex anastomosis with Profunda brachii artery The posterior humeral circumflex artery anastomoses with an ascending branch of the profunda brachii artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B . The lateral thoracic and subscapular arteries do not anastomose with the profunda brachii artery. Option: D. The superior ulnar collateral and radial recurrent arteries arise inferior to the origin of the profunda brachii artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient complains of having pain with repeated movements of his thumb (claudication). His physician performs Allen’s test and finds an insufficiency of the radial artery. Which of the following conditions would be a result of radial artery stenosis?", "options": [{"label": "A", "text": "A marked decrease in the blood flow in the superficial palmar arterial arch", "correct": false}, {"label": "B", "text": "Decreased pulsations in the artery passing superficial to the flexor retinaculum.", "correct": false}, {"label": "C", "text": "Ischemia of the entire extensor muscles of the forearm.", "correct": false}, {"label": "D", "text": "A marked decrease in the blood flow in the princeps pollicis artery.", "correct": true}], "correct_answer": "D. A marked decrease in the blood flow in the princeps pollicis artery.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A marked decrease in the blood flow in the princeps pollicis artery. Radial artery and Deep Palmar arch: The radial artery divides into the princeps pollicis artery and the deep palmar arterial arch. Thus, stenosis of the radial artery results in decreased blood flow in the princeps pollicis artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Decreased pulsations in the artery passing superficial to the flexor retinaculum. The Superficial palmar arterial arch is formed primarily by the ulnar artery, which passes superficial to the flexor retinaculum. Option: C. Ischemia of the entire extensor muscles of the forearm. The extensor compartment of the forearm receives blood from the posterior interosseous artery, which arises from the common interosseous branch of the ulnar artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 14 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The only medial branch from the external carotid artery:", "options": [{"label": "A", "text": "Lingual Artery", "correct": false}, {"label": "B", "text": "Facial artery", "correct": false}, {"label": "C", "text": "Occipital artery", "correct": false}, {"label": "D", "text": "Ascending pharyngeal artery", "correct": true}], "correct_answer": "D. Ascending pharyngeal artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ascending pharyngeal artery A scending pharyngeal artery arises from the medial surface of the external carotid artery between the internal carotid artery and pharynx to reach the base of the cranium. It is the smallest branch of the external carotid artery.</p>\n<p><strong>Highyeild:</strong></p><p>The ascending pharyngeal artery is an artery in the neck that supplies the pharynx, developing from the proximal part of the embryonic second aortic arch.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Lingual Artery The lingual artery arises from the anterior surface of the external carotid artery in the neck. Option B. Facial artery The facial artery arises from the anterior surface of the external carotid, and has a tortuous route along the nasolabial fold towards the medial canthus of the eye. It moves beneath the digastric and stylohyoid muscles and it will pass through the submandibular gland. Option C. Occipital artery The occipital artery is a posterior branch of the external carotid artery , in the posterior portion of the neck and the occipital region of the head. The occipital artery supplies several muscles of the posterior neck along with trapezius, sternocleidomastoid and occipitofrontalis muscles.</p>\n<p><strong>Extraedge:</strong></p><p>Ascending pharyngeal artery has 2 Branches:- Inferior tympanic artery & Posterior meningeal artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All the following are branches of subclavian artery, except:", "options": [{"label": "A", "text": "Vertebral Artery", "correct": false}, {"label": "B", "text": "Thyrocervical artery", "correct": false}, {"label": "C", "text": "Subscapular artery", "correct": true}, {"label": "D", "text": "Internal thoracic artery", "correct": false}], "correct_answer": "C. Subscapular artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Subscapular artery Subscapular artery is the largest branch from the 3rd part of the axillary artery.</p>\n<p><strong>Highyeild:</strong></p><p>Branches Of Subclavian Artery Part Branches First part From its origin to the medial border of scalenus anterior Vertebral arter Internal thoracic artery Thyrocervical trunk Second part Lying behind scalenus anterior Costocervical trunk Third part Between the lateral border of scalenus anterior and the outer border of the first rib Dorsal scapular artery ' Branches of Subclavian artery</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Vertebral Artery The vertebral artery is a major artery in the neck. It branches from the subclavian artery, where it arises from the posterosuperior portion of the subclavian artery. Option B. Thyrocervical artery The thyrocervical trunk is an artery of the neck. It is a branch of the subclavian artery. It arises from the first portion of this vessel, between the origin of the subclavian artery and the inner border of the scalenus anterior muscle. Option D. Internal thoracic artery The internal thoracic artery branches off of the proximal portion of the subclavian artery and begins its descent along the inner surface of the anterior chest wall.</p>\n<p><strong>Extraedge:</strong></p><p>Subclavian artery is divided into three parts: The first part, also known as the pre scalene part,extends from the origin of the vessel to the medial border of the scalenus anterior muscle. The second part, also known as the scalene part, lies behind the scalenus anterior muscle. The third part, also known as the post scalene part,extends from the lateral margin of the muscle to the outer border of the first rib, where it becomes the axillary artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Blood supply to inner ear is derived from:", "options": [{"label": "A", "text": "Superior Cerebellar Artery", "correct": false}, {"label": "B", "text": "Posterior inferior cerebellar artery", "correct": false}, {"label": "C", "text": "Middle cerebral", "correct": false}, {"label": "D", "text": "Anterior inferior cerebellar artery", "correct": true}], "correct_answer": "D. Anterior inferior cerebellar artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior inferior cerebellar artery The arterial supply of the inner ear is derived mainly from the labyrinthine artery, which is a branch from anterior inferior cerebellar artery or sometimes from the basilar artery.</p>\n<p><strong>Highyeild:</strong></p><p>Anterior inferior cerebellar artery Anterior inferior cerebellar artery, accompanies the vestibulocochlear nerve. And, partly the blood supply of the inner ear is derived from the stylomastoid branch of the posterior auricular artery. As Anterior inferior cerebellar artery enters the inner ear, the labyrinthine artery divides into the anterior vestibular artery and the common cochlear artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Superior Cerebellar Artery The superior cerebellar artery (SCA) usually originates from the basilar artery . The superior vermis, the tectum, and superior surface of the cerebellar hemispheres are supplied by the SCA. Option B. Posterior inferior cerebellar artery The posterior inferior cerebellar artery ( PICA ) is the largest branch of the vertebral artery. It is one of the three main arteries that supply blood to the cerebellum. Option C. Middle cerebral artery The primary function of the MCA is to supply specific regions of brain parenchyma with oxygenated blood. The cortical branches of the MCA irrigate the brain parenchyma of the primary motor and somatosensory cortical areas of the face, trunk and upper limbs, apart from the insular and auditory cortex.</p>\n<p><strong>Extraedge:</strong></p><p>The labyrinthine artery may become occluded.This can cause loss of hearing and balance on the affected side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Arrow marked artery in the image is a branch from which part of the maxillary artery?", "options": [{"label": "A", "text": "1st Part", "correct": true}, {"label": "B", "text": "2nd part", "correct": false}, {"label": "C", "text": "3rd part", "correct": false}, {"label": "D", "text": "4th part", "correct": false}], "correct_answer": "A. 1st Part", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681254381-QTDA017004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1st Part Marked artery is a mental artery which arises from an inferior alveolar branch of maxillary artery arising from its 1st part.</p>\n<p><strong>Highyeild:</strong></p><p>Branches of Maxillary artery</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. 2nd part, option C. 3rd part and option D. 4th part all are incorrect options because, Marked artery is a mental artery which arises from an inferior alveolar branch of maxillary artery arising from its 1st part.</p>\n<p><strong>Extraedge:</strong></p><p>The mental artery is a terminal branch of the inferior alveolar artery which itself is a branch of the first part of the maxillary artery. It emerges onto the face from the mandibular canal with the mental nerve at the mental foramen, and supplies muscles and skin in the chin region. The mental artery anastomoses with the inferior labial and submental arteries.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The structure which lies beneath the hyoglossus muscle is?", "options": [{"label": "A", "text": "Lingual Artery", "correct": true}, {"label": "B", "text": "Lingual nerve", "correct": false}, {"label": "C", "text": "Hypoglossal nerve", "correct": false}, {"label": "D", "text": "Submandibular ganglion", "correct": false}], "correct_answer": "A. Lingual Artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lingual Artery Deep relations of the hyoglossus: Inferior longitudinal muscle of tongue. Genioglossus muscle anteriorly. Middle constrictor of pharynx posteriorly. Glossopharyngeal nerve. Stylohyoid ligament. Lingual artery.</p>\n<p><strong>Highyeild:</strong></p><p>Superficial relations of the hyoglossus: Hypoglossal nerve crosses the lower part of muscle from behind forwards. Lingual nerve crosses the upper part of muscle from behind forwards. Deep part of the submandibular gland and submandibular duct. The gland lies in the middle of hyoglossus muscle and the duct lies between the gland and the muscle. Submandibular ganglion lies between the lingual nerve and deep part of the submandibular gland. Styloglossus muscle— interdigitate with hyoglossus. Mylohyoid muscle overlaps the hyoglossus anterosuperiorly.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Lingual nerve superficially crosses the upper part of muscle from behind forwards. Option C. Hypoglossal nerve superficially crosses the lower part of muscle from behind forwards. Option D. Submandibular ganglion lies between the lingual nerve and deep part of the submandibular gland.</p>\n<p><strong>Extraedge:</strong></p><p>Structures passing deep to posterior border of hyoglossus: From above downwards, these are: Glossopharyngeal nerve. Stylohyoid ligament. Lingual artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Middle thyroid vein drains into:", "options": [{"label": "A", "text": "External Jugular Vein", "correct": false}, {"label": "B", "text": "Anterior jugular vein", "correct": false}, {"label": "C", "text": "Internal jugular vein", "correct": true}, {"label": "D", "text": "Brachiocephalic vein", "correct": false}], "correct_answer": "C. Internal jugular vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Internal jugular vein The thyroid is drained by the superior, middle and inferior thyroid veins. The middle thyroid vein is a short, wide channel which emerges at the middle of the lobe and soon enters the internal jugular vein.</p>\n<p><strong>Highyeild:</strong></p><p>Venous drainage of thyroid gland The superior thyroid vein emerges at the upper pole and accompanies the superior thyroid artery. It ends in the internal jugular vein. The middle thyroid vein is a short, wide channel which emerges at the middle of the lobe and soon enters the internal jugular vein. The inferior thyroid veins emerge at the lower border of isthmus. They form a plexus in front of the trachea, and drain into the left brachiocephalic vein. A fourth thyroid vein (Kocher) may emerge between the middle and inferior veins, and drain into the internal jugular vein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options A. External Jugular Vein, Option B. Anterior jugular vein and Option D. Brachiocephalic veins are incorrect because the middle thyroid vein is a short, wide channel which emerges at the middle of the lobe and soon enters the internal jugular vein.</p>\n<p><strong>Extraedge:</strong></p><p>The inferior thyroid vein is a paired vein in the lower neck. The left and right inferior thyroid veins arise at the inferior poles of the respective lobes of the thyroid gland. They have a short inferior course, each draining into the respective brachiocephalic vein.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Recurrent laryngeal nerve lies in close relation to which of the following arteries?", "options": [{"label": "A", "text": "Superior Thyroid Artery", "correct": false}, {"label": "B", "text": "Middle thyroid artery", "correct": false}, {"label": "C", "text": "Inferior thyroid artery", "correct": true}, {"label": "D", "text": "left subclavian artery", "correct": false}], "correct_answer": "C. Inferior thyroid artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior thyroid artery Inferior thyroid artery related to recurrent laryngeal nerve. Superior thyroid artery related to external laryngeal nerve</p>\n<p><strong>Highyeild:</strong></p><p>Inferior thyroid artery: It is a branch of thyrocervical trunk from the first part of the subclavian artery. It first runs upwards along the medial border of scalenus anterior, and then passes medially behind the carotid sheath to reach the back of the thyroid lobe, where it is intimately related to the recurrent laryngeal nerve. The recurrent laryngeal nerve presents a variable relationship with the artery. It may pass behind or in front of the loop of the artery or between the branches of the artery. The artery gives 4 or 5 branches, The inferior thyroid artery supplies the lower two-third of the lobe and lower half of the isthmus. Thyroid gland arterial supply and nerve supply</p>\n<p><strong>Extraedge:</strong></p><p>Superior thyroid artery: It is a branch of the external carotid artery. It runs downwards and forwards in company with the external laryngeal nerve, which it leaves near the upper pole of the thyroid lobe.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not a branch of the external carotid artery which takes part in Kiesselbach’s plexus?", "options": [{"label": "A", "text": "Sphenopalatine Artery", "correct": false}, {"label": "B", "text": "Greater palatine artery", "correct": false}, {"label": "C", "text": "Anterior ethmoidal artery", "correct": true}, {"label": "D", "text": "Septal branch of superior labial artery", "correct": false}], "correct_answer": "C. Anterior ethmoidal artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior ethmoidal artery Anterior ethmoidal artery- from ophthalmic artery- from internal carotid artery.</p>\n<p><strong>Highyeild:</strong></p><p>Little’s area : It is an area in the anteroinferior part of the nasal septum just above the vestibule. It is highly vascular. Here the septal branches of the anterior ethmoidal sphenopalatine, greater palatine, and superior labial arteries anastomose to form a vascular plexus called Kiesselbach’s plexus. This area of nasal septum is the commonest site of epistaxis (nose bleeding) in children and young adults usually due to finger nail trauma following picking of the nose. Little’s area arterial supply</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Sphenopalatine Artery The sphenopalatine artery is a terminal branch of the internal maxillary artery originating from the external carotid artery system. The SPA is the major blood vessel to the nasal cavity mucosa: supplying the superior, middle, and inferior turbinate; lateral nasal wall; and nasal septum. Option B. Greater palatine artery The greater palatine artery is a branch of the descending palatine artery (branch of the 3rd part of the maxillary artery). The blood vessel supplies the hard palate mucosa, gingival tissue, and palatine tonsils. Option D. Septal branch of superior labial artery At the nasal septum, the columellar arteries and septal branches of the facial artery which branch off the external carotid artery become part of the Kiesselbach plexus at the anterior part of the nasal septum.</p>\n<p><strong>Extraedge:</strong></p><p>Arterial Supply of Nasal Septum The nasal septum is supplied by the following arteries: Septal branch of the anterior ethmoidal artery (a branch of ophthalmic artery). Septal branch of the posterior ethmoidal artery (a branch of ophthalmic artery). Septal branch of the sphenopalatine artery (a branch of maxillary artery). Septal branch of the greater palatine artery (a branch of maxillary artery). Septal branch of the superior labial artery (a branch of facial artery).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Sternocleidomastoid is supplied by all, except:", "options": [{"label": "A", "text": "Occipital", "correct": false}, {"label": "B", "text": "Posterior auricular Artery", "correct": true}, {"label": "C", "text": "Superior thyroid Artery", "correct": false}, {"label": "D", "text": "Thyrocervical trunk", "correct": false}], "correct_answer": "B. Posterior auricular Artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior auricular Artery The upper third of the SCM muscle was constantly supplied by branches of the occipital artery, and also by posterior auricular artery. The middle third of the SCM muscle receives its blood supply from a branch of the superior thyroid artery, the external carotid artery, or branches of both. The lower third of the muscle was supplied by a branch arising from the suprascapular artery, the transverse cervical artery , the thyrocervical trunk, or the superficial cervical artery. Therefore, all arteries mentioned in options supplies blood to sternocleidomastoid muscle, if one of the options has to be chosen then it is the posterior auricular artery.</p>\n<p><strong>Highyeild:</strong></p><p>Arterial supply of Sternocleidomastoid muscle—one branch each from superior thyroid artery and suprascapular artery and two branches from the occipital artery supply the big muscle. Veins follow the arteries The sternocleidomastoid is supplied by branches of the following arteries: Upper part, by occipital and partly by posterior auricular arteries. Middle part, by superior thyroid artery. Lower part, by suprascapular artery (one of the branch of thyrocervical trunk) The knowledge of arterial supply is important to make muscle flap in reconstructive surgery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Occipital The upper third of the SCM muscle was constantly supplied by branches of the occipital artery. Option C. Superior thyroid Artery The middle third of the SCM muscle receives its blood supply from a branch of the superior thyroid artery, the external carotid artery, or branches of both. Option D. Thyrocervical trunk The lower third of the muscle was supplied by a branch arising from the suprascapular artery, the transverse cervical artery , the thyrocervical trunk, or the superficial cervical artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 19 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Posterior cord supplies:", "options": [{"label": "A", "text": "Teres Minor", "correct": true}, {"label": "B", "text": "Pectoralis", "correct": false}, {"label": "C", "text": "Coracobrachialis", "correct": false}, {"label": "D", "text": "Long Head of Biceps", "correct": false}], "correct_answer": "A. Teres Minor", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Teres Minor Teres minor muscle is innervated by the posterior branch of the axillary nerve which is a branch from the posterior cord of the brachial plexus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Pectoralis- Pectoralis major and minor are innervated by medial and lateral pectoral nerves, which are branches of the medial and lateral cord of the brachial plexus. Option: C. Coracobrachialis is innervated by the musculocutaneous nerve , which is a branch of the lateral cord of the brachial plexus. Option: D. Long head of biceps- The biceps brachii is innervated by the musculocutaneous nerve , which is a branch of the lateral cord of the brachial plexus.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Coracobrachialis is pierced by which nerve:", "options": [{"label": "A", "text": "Axillary", "correct": false}, {"label": "B", "text": "Median", "correct": false}, {"label": "C", "text": "Musculocutaneous", "correct": true}, {"label": "D", "text": "Ulnar", "correct": false}], "correct_answer": "C. Musculocutaneous", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Musculocutaneous Musculocutaneous nerve piercing Coracobrachialis</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The little finger of the hand corresponds to which of the following dermatomes:", "options": [{"label": "A", "text": "C6", "correct": false}, {"label": "B", "text": "C7", "correct": false}, {"label": "C", "text": "C8", "correct": true}, {"label": "D", "text": "T1", "correct": false}], "correct_answer": "C. C8", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C8 The C8 n erve supplies the little finger, the medial side of the hand, and the forearm (i.e. the inferior aspect of the outstretched limb) C3 and C4 nerves supply the region at the base of the neck extending laterally over the shoulder The C5 n erve supplies the arm laterally (i.e., on the superior aspect of the abducted limb) Cutaneous Innervation o f the Upper Limb</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A . C6 : The C6 nerve supplies the forearm laterally and the thumb. Option: B . C7: C7 nerve supplies the middle and ring fingers (or middle three fingers) and the middle of the posterior surface of the limb Option: D . T1: The T1 nerve supplies the middle of the forearm to the axilla. The T2 nerve supplies a small part of the arm and the skin of the axilla. (This is not indicated on the Keegan and Garrett map: however, pain experienced during a heart attack, considered to be mediated by Tl and T2, is commonly described as radiating down the medial side of the left arm.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient is suffering from loss of sensation along the medial border of the forearm and clawing of the hand. Which cord or trunk of the brachial plexus is involved?", "options": [{"label": "A", "text": "Upper Trunk", "correct": false}, {"label": "B", "text": "Lower Trunk", "correct": true}, {"label": "C", "text": "Lateral Cord", "correct": false}, {"label": "D", "text": "Posterior Cord", "correct": false}], "correct_answer": "B. Lower Trunk", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lower Trunk</p>\n<p><strong>Highyeild:</strong></p><p>Klumpke’s Paralysis Site of injury : The lower t runk of the brachial plexus. Cause of injury: Undue abduction of the arm, as in clutching something with the hands after a fall from a height, or sometimes in a birth injury. Nerve roots involved: Mainly T1 and partly C8. Muscles paralyzed: Intrinsic muscles of the hand (T1). Ulnar flexors of the wrist and fingers (C8). Deformity and position of the hand: Claw hand due to the unopposed action of the long flexors and extensors of the fingers. In a claw hand, there is hyperextension at the metacarpophalangeal joints and flexion at the interphalangeal joints. Disability: Medial claw hand , and Cutaneous anesthesia and analgesia in a narrow zone along the ulnar border of the forearm and hand.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Uppe r Trunk: Erb's palsy : a common injury of the upper brachial plexus nerves, causing numbness and loss of motion around the shoulder and an inability to flex the elbow, lift an arm or bring objects to the mouth Option: C. Latera l cord: Lateral cord of the brachial plexus mainly involves injury of the musculocutaneous nerve causing paralysis of the Biceps brachii, Coracobrachialis, and Brachialis muscle. Option: D. Posterior cord: Posterior cord of the brachial plexus mainly involve injury of the axillary nerve and Radial nerve causing paralysis of the Deltoid, Teres minor, and forearm extensor muscles.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following is a branch from the trunk of the brachial plexus?", "options": [{"label": "A", "text": "Suprascapular Nerve", "correct": true}, {"label": "B", "text": "Long Thoracic Nerve", "correct": false}, {"label": "C", "text": "Anterior Thoracic Nerve", "correct": false}, {"label": "D", "text": "Dorsal Scapular Nerve", "correct": false}], "correct_answer": "A. Suprascapular Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Suprascapular Nerve Nerve to subclavius and suprascapular nerve - both arise from the trunk of the brachial plexus Brachial plexus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B . Long thoracic nerve: The long thoracic nerve is a branch of the root of the brachial plexus derived from cervical nerves C5-C7 that innervates the serratus anterior muscle. Option C . Anterior thoracic nerve: Anterior thoracic nerves may refer to the Lateral pectoral nerve and the Medial pectoral nerve and both are branches of the lateral and medial cord of the brachial plexus respectively. Option: D. Dorsal scapular nerve: The dorsal scapular nerve is a branch of the root of the brachial plexus, usually derived from the ventral ramus of cervical nerve C5. It provides motor innervation to the rhomboid major muscle, rhomboid minor muscle, and levator scapulae muscle.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Following the surgical removal of firm nodular swelling in the right breast and exploration of the right axilla, the patient was found to have a winged scapula. Most likely this could have occurred due to injury of:", "options": [{"label": "A", "text": "Subscapular Nerve", "correct": false}, {"label": "B", "text": "Coracoid Process of Scapula", "correct": false}, {"label": "C", "text": "Long Thoracic Nerve", "correct": true}, {"label": "D", "text": "Circumflex Scapular Artery", "correct": false}], "correct_answer": "C. Long Thoracic Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Long Thoracic Nerve Paralysis of the serratus anterior produces ‘ winging of scapula’ in which the inferior angle and the medial border of the scapula are unduly prominent. The nerve to the serratus anterior is a branch of the brachial plexus. It arises from roots C5, C6, and C7 and is also called the long thoracic nerve . The patient is unable to do any pushing action, nor can he raise his arm above the head. Any attempt to do these movements makes the inferior angle of the scapula still more prominent.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following are the features of musculocutaneous nerve injury at the axilla, except:", "options": [{"label": "A", "text": "Loss of flexion at the shoulder joint", "correct": false}, {"label": "B", "text": "Loss of extension at the elbow", "correct": true}, {"label": "C", "text": "Loss of supination of the forearm", "correct": false}, {"label": "D", "text": "Loss of sensation on the radial side of the forearm", "correct": false}], "correct_answer": "B. Loss of extension at the elbow", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Loss of extension at the elbow Loss of extension at the elbow is due to injury of the Triceps muscle innervated by the radial nerve. The musculocutaneous nerve is well protected within the axilla and injury is relatively uncommon. Characteristic mechanisms of injury include penetrating trauma to the axilla (e.g. stabbing), and iatrogenic injury resulting from heavy retraction during the deltopectoral approach to the shoulder. Motor functions – coracobrachialis, biceps brach ii, and b rachialis muscles are affected: Flexion at the shoulder and elbow is weakened but can still be performed by the pectoralis major and brachioradialis respectively. Supination of the forearm is weak, but can still be performed by the brachioradialis. Sensory functions – loss of sensation over the lateral side of the forearm.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The patient presented with a fall on an outstretched hand. The X-ray taken is shown below. Which of the following vessel is most likely involved?", "options": [{"label": "A", "text": "Ulnar Artery", "correct": false}, {"label": "B", "text": "Radial Artery", "correct": false}, {"label": "C", "text": "Brachial Artery", "correct": true}, {"label": "D", "text": "Cubital Vein", "correct": false}], "correct_answer": "C. Brachial Artery", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683027020-QTDA096008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Brachial Artery This is a case of supracondylar fracture of the humerus, with distal condylar fragments displaced in a posterior direction. It can lead to tear or entrapment of the brachial artery. If left untreated could lead to Volkmann’s contracture (permanent flexion contracture of the hand at the wrist, resulting in a claw-like deformity of the hand and fingers. The most common nerve injured in the supracondylar fracture of the humerus is MEDIAN NERVE.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Ulna r Artery: The ulnar artery arises as a large terminal branch of the brachial artery at the inferior aspect of the cubital fossa, so not injured at supracondylar fracture of the humerus. Option B. Radia l artery: The radial artery originates at the cubital fossa as one of the two terminal branches of the brachial artery, so not injured at the supracondylar fracture of the humerus. Option D. Cubita l vein: Cubital vein is a superficial vein of the upper limb. It lies in the cubital fossa superficial to the bicipital aponeurosis. It connects the cephalic vein and the basilic vein. It becomes prominent when pressure is applied.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 22-year-old pregnant woman was admitted emergently to the hospital after the baby had begun to appear at the introitus. The baby had presented in the breech position, and it had been necessary to exert considerable traction to complete the delivery. The newborn baby is shown in the image. Which of the following structures was most likely injured by the trauma of childbirth?", "options": [{"label": "A", "text": "Radial Nerve", "correct": false}, {"label": "B", "text": "Upper trunk of the brachial plexus", "correct": true}, {"label": "C", "text": "Lower trunk of the brachial plexus", "correct": false}, {"label": "D", "text": "Median, ulnar, and radial nerves", "correct": false}], "correct_answer": "B. Upper trunk of the brachial plexus", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683027038-QTDA096009IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Upper trunk of the brachial plexus During a breech delivery as described here, downward traction is applied to the shoulders and upper limbs as the baby is forcibly extracted from the birth canal. This exerts traction on the upper cord of the brachial plexus, often causing a traction injury from which the baby can often recover. If the roots of C5 and C6 are avulsed from the spinal cord, the injury is permanent.</p>\n<p><strong>Highyeild:</strong></p><p>Erb’s Paralysis Site of injury: One region of the upper trunk of the brachial plexus is called Erb’s point . Six nerves meet here . Injury to the upper trunk causes Erb’s paralysis. Causes of injury: Undue separation of the head from the shoulder, which is commonly encountered in the following. Birth injury/difficult childbirth Fall on the shoulder During anesthesia. Nerve roots involved: Mainly C5 and partly C6. Muscles paralyzed: Mainly biceps brachii, deltoid, brachialis, and brachioradialis. Partly supraspinatus, infraspinatus, and supinator. Deformity and position of the limb: Arm: Hangs by the side; it is adducted and medially rotated. Forearm: Extended and pronated. The deformity is known as ‘policeman’s tip hand’ or waiter’s tip hand or ‘porter’s tip hand’</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Radial Nerve entrapment can cause loss of the ability to supinate the forearm while still being able to extend it. Loss of forearm extension can occur when the radial nerve is injured in the axilla Option C. Lower trunk of the brachial plexus The lower trunk of the brachial plexus injury causes Klumpke’s Paralysis Site of injury: The lower trunk of the brachial plexus. Cause of injury: Undue abduction of the arm, as in clutching something with the hands after a fall from a height, or sometimes in a birth injury. Nerve roots involved: Mainly T1 and partly C8. Option D. Median, ulnar, and radial nerves if injured present with multiple deformities and not just policeman tip deformity.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The following statements concerning the lateral cord of the brachial plexus are true except?", "options": [{"label": "A", "text": "It contains sympathetic nerve fibers", "correct": false}, {"label": "B", "text": "It has a branch that supplies the pectoralis major muscle", "correct": false}, {"label": "C", "text": "It has a branch that supplies the skin on the lateral side of the forearm", "correct": false}, {"label": "D", "text": "It has a branch that supplies the skin on the lateral side of the upper arm", "correct": true}], "correct_answer": "D. It has a branch that supplies the skin on the lateral side of the upper arm", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>It has a branch that supplies the skin on the lateral side of the upper arm The skin on the lateral side of the upper arm covering the upper half of the deltoid muscle is innervated by the supraclavicular nerves (C3 and 4) , and the skin covering the lower half of the deltoid muscle is innervated by the upper lateral cutaneous nerve of the arm (C5 and 6) from the axillary nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. It contains sympathetic nerve fibers Root Value of Lateral cord of Brachial plexus- (C5–C7) Sympathetic nerves for the upper limb are derived from spinal segments T2 to T6 . Most of the vasoconstrictor fibers supplying the arteries emerge from segments T2 and T3. The preganglionic fibers arise from lateral horn cells and emerge from the spinal cord through ventral nerve roots. Passing through white rami communicantes, they reach the sympathetic chain. They ascend within the chain and end in the middle cervical, inferior cervical, and first thoracic ganglia. Postganglionic fibers from the middle cervical ganglion pass through grey rami communicantes to reach C5 and C6 nerve roots. Postganglionic fibers from the inferior cervical ganglion pass through grey rami communicantes to reach C7 and C8 nerve roots. Postganglionic fibers from the first thoracic sympathetic ganglion pass through grey rami communicantes to reach T1 nerve roots. Option: B. It has a branch that supplies the pectoralis major muscle The lateral pectoral nerve branch of the lateral cord supplies the pectoralis major muscle. Option: C. It has a branch that supplies the skin on the lateral side of the forearm. The musculocutaneous nerve branch of the lateral cord gives lateral cutaneous nerve of the forearm</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 20-year-old man fell from the parallel bar during the Olympic trial. A neurologic examination reveals that he has a lesion of the lateral cord of the brachial plexus. Which of the following muscles is most likely weakened by this injury?", "options": [{"label": "A", "text": "Subscapularis", "correct": false}, {"label": "B", "text": "Teres Major", "correct": false}, {"label": "C", "text": "Latissimus Dorsi", "correct": false}, {"label": "D", "text": "Pectoralis Major", "correct": true}], "correct_answer": "D. Pectoralis Major", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pectoralis Major The pectoralis major is innervated by the lateral and medial pectoral nerves originating from the lateral and medial cords of the brachial plexus, respectively The subscapularis, teres major, latissimus dorsi, and teres minor muscles are innervated by nerves originating from the posterior cord of the brachial plexus.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The given clinical condition is due to involvement of the nerve which is a branch from which part of the brachial plexus?", "options": [{"label": "A", "text": "Root", "correct": true}, {"label": "B", "text": "Trunk", "correct": false}, {"label": "C", "text": "Division", "correct": false}, {"label": "D", "text": "Cord", "correct": false}], "correct_answer": "A. Root", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683027048-QTDA096012IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Root Diagnosis- winging of scapula- The most common etiology of a winged scapula is usually due to damage or impaired innervation to the serratus anterior muscle. The nerve that innervates this muscle is the long thoracic nerve which is a branch from the root of the brachial plexus. The long thoracic nerve is not a branch trunk, cord, or division of the brachial plexus.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The brachial plexus gives rise to the nerves of the upper limb. Which of these statements about its branches is correct?", "options": [{"label": "A", "text": "The terminal branch of the medial cord is the ulnar nerve", "correct": true}, {"label": "B", "text": "The terminal branch of the posterior cord is the median nerve", "correct": false}, {"label": "C", "text": "The axillary nerve is a branch of the lateral cord", "correct": false}, {"label": "D", "text": "The radial nerve arises from the medial cord", "correct": false}], "correct_answer": "A. The terminal branch of the medial cord is the ulnar nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The terminal branch of the medial cord is the ulnar nerve Option: B. The median nerve arises from the medial and lateral cords of the brachial plexus. Option: C. The axillary nerve is a branch of the posterior cord Option: D. The radial nerve arises from the posterior cord.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following are muscles innervated by branches from the brachial plexus except:", "options": [{"label": "A", "text": "Supraspinatus", "correct": false}, {"label": "B", "text": "Latissimus Dorsi", "correct": false}, {"label": "C", "text": "Rhomboid Major", "correct": false}, {"label": "D", "text": "Trapezius", "correct": true}], "correct_answer": "D. Trapezius", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Trapezius Nerve supply of trapezius muscle: Spinal part of the accessory nerve(cranial nerve XII) Branches from C-3, C-4 (proprioceptive)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Supraspinatus The suprascapular nerve (C5) innervates the supraspinatus muscle as well as the infraspinatus muscle. It comes from the upper trunk of the brachial plexus. Option: B. Latissimus dorsi The latissimus dorsi is innervated by the sixth, seventh, and eighth cervical nerves through the thoracodorsal nerve, a branch of the posterior cord of the brachial plexus. Option: C. Rhomboid major The rhomboid major, like the rhomboid minor, is innervated by the ventral primary ramus via the dorsal scapular nerve (C5)T branch from the root of the brachial plexus.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Concerning the brachial plexus, which of the following is false?", "options": [{"label": "A", "text": "Formed by spinal nerve C4-C7", "correct": true}, {"label": "B", "text": "Most common site of injury is the upper trunk", "correct": false}, {"label": "C", "text": "Injury may occur during a breech delivery", "correct": false}, {"label": "D", "text": "Radial nerve is a branch of the posterior cord", "correct": false}], "correct_answer": "A. Formed by spinal nerve C4-C7", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Formed by spinal nerve C4-C7 Brachial plexus is contributed by the spinal nerve C5-8, T1, not C4-7</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: C. Obstetric brachial palsy following breech delivery is a typical group: upper lesions predominate with a great number of upper root avulsions and phrenic nerve lesions. Lower trunk(C-8, T1) injury results in claw hand deformity.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the statements about the musculocutaneous nerve is correct?", "options": [{"label": "A", "text": "It is a branch of the medial cord of the brachial plexus", "correct": false}, {"label": "B", "text": "It pierces the brachialis to enter the anterior compartment of the arm", "correct": false}, {"label": "C", "text": "Brachioradialis is innervated by one of its branches", "correct": false}, {"label": "D", "text": "It contributes to the innervation of the shoulder joint", "correct": true}], "correct_answer": "D. It contributes to the innervation of the shoulder joint", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>It contributes to the innervation of the shoulder joint The musculocutaneous nerve gives a branch to the shoulder joint as it crosses it. It is the terminal branch of the lateral cord of the brachial plexus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Musculocutaneous nerve is a branch of the lateral cord of the Brachial Option: B. Musculocutaneous leaves the axilla and pierces the coracobrachialis muscle near its point of insertion on the humerus. Option: C: Brachioradialis is innervated by the radial nerve.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral arteries. Erb's point is at the junction of C5 and C6 roots. (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 26 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The doctor is testing the jaw-jerk reflex in a patient by tapping gently on the right masseter muscle and observing the elevation of the mandible. What is the location of the neuronal cell bodies of the proprioceptive fibres mediating the jaw-jerk reflex?", "options": [{"label": "A", "text": "Mesencephalic Trigeminal Nucleus", "correct": true}, {"label": "B", "text": "Motor trigeminal nucleus", "correct": false}, {"label": "C", "text": "Principal (main) trigeminal nucleus", "correct": false}, {"label": "D", "text": "Spinal trigeminal nucleus", "correct": false}], "correct_answer": "A. Mesencephalic Trigeminal Nucleus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Mesencephalic Trigeminal Nucleus The jaw-jerk reflex is a monosynaptic (stretch) reflex for the masseter muscle. Proprioceptive fibres from the muscle travel by way of the trigeminal nerve back to their cell bodies in the mesencephalic trigeminal nucleus.</p>\n<p><strong>Highyeild:</strong></p><p>The jaw jerk reflex or the masseter reflex is a stretch reflex used to test the status of a patient's trigeminal nerve (cranial nerve V). The mandible—or lower jaw—is tapped at a downward angle just below the lips at the chin while the mouth is held slightly open. In response, the masseter muscles will jerk the mandible upwards. Normally this reflex is absent or very slight. However, in individuals with upper motor neuron lesions, the jaw jerk reflex can be quite pronounced</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Projections from this nucleus synapse on motor neurons of the motor trigeminal nucleus (choice B) which elicits contraction of the masseter muscle. Option: C, D. The principal (main) trigeminal nucleus (choice C) receives light touch sensory information from the face, whereas the spinal trigeminal nucleus (choice D) receives pain and temperature sensations. The trigeminal (gasserian) ganglion contains the cell bodies of all sensory neurons projecting to the principal (main) and spinal trigeminal nuclei.</p>\n<p><strong>Extraedge:</strong></p><p>The jaw jerk reflex can be classified as a dynamic stretch reflex. As with most other reflexes, the response to the stimulus is monosynaptic, with sensory neurons of the trigeminal mesencephalic nucleus sending axons to the trigeminal motor nucleus, which in turn innervates the masseter. This reflex is used to judge the integrity of the upper motor neurons projecting to the trigeminal motor nucleus. Both the sensory and motor aspects of this reflex are through CN V.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 1-year-old infant presents with cardiomegaly and congestive heart failure. She has increased intracranial pressure with hydrocephalus and cranial bruit. A vein of the Galen aneurysm, revealed by MRI, is shown to compress the aqueduct of Sylvius, the posterior part of the third ventricle, and the splenium of the corpus callosum. Normally, the cerebral vein of Galen joins with which dural venous sinus?", "options": [{"label": "A", "text": "Inferior Sagittal Sinus", "correct": true}, {"label": "B", "text": "Sigmoid sinus", "correct": false}, {"label": "C", "text": "Superior petrosal sinus", "correct": false}, {"label": "D", "text": "Superior sagittal sinus", "correct": false}], "correct_answer": "A. Inferior Sagittal Sinus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior Sagittal Sinus The great cerebral vein of Galen joins with the inferior sagittal sinus to form the straight sinus. The latter drains into the transverse sinus.</p>\n<p><strong>Highyeild:</strong></p><p>The great cerebral vein begins just below the pineal gland by the union of two pairs of veins; internal cerebral veins and basal veins of Rosenthal. The vein is short and valveless and curves backwards and upwards through the quadrigeminal cistern around the posterior border of the splenium of the corpus callosum to drain into the confluence of the inferior sagittal sinus and the straight sinus. Great cerebral vein of Galen</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: D. The superior sagittal sinus (choice D) drains posteriorly into the transverse sinus. Option: B. The transverse sinus which runs bilaterally on the posterior wall of the posterior cranial fossa becomes the sigmoid sinus (choice B) which flows into the internal jugular vein. Option: C. The superior petrosal sinus (choice C) extends from the cavernous sinus to the beginning of the sigmoid sinus.</p>\n<p><strong>Extraedge:</strong></p><p>T he great cerebral vein is one of the deep cerebral veins . Other deep cerebral veins are the internal cerebral veins , formed by the union of the superior thalamostriate vein and the superior choroid vein at the interventricular foramina. The internal cerebral veins can be seen on the superior surfaces of the caudate nuclei and thalami just under the corpus callosum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 57-year-old female patient is in a coma and had suffered a major stroke. The attending neurologist is very concerned because the patient is developing ataxic breathing. The pneumotaxic centre and apneustic centres of the brain are located in which of the following?", "options": [{"label": "A", "text": "Diencephalon", "correct": false}, {"label": "B", "text": "Midbrain", "correct": false}, {"label": "C", "text": "Pons", "correct": true}, {"label": "D", "text": "spinal cord", "correct": false}], "correct_answer": "C. Pons", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pons The pneumotaxic centre is located in the upper one-third of the pons, whereas the apneustic centre is in the lower two-thirds. The apneustic centre promotes inspiration and the pneumotaxic centre, expiration.</p>\n<p><strong>Highyeild:</strong></p><p>The respiratory centre is located in the medulla oblongata and pons, in the brainstem. The respiratory centre is made up of three major respiratory groups of neurons, two in the medulla and one in the pons. In the medulla, they are the dorsal respiratory group and the ventral respiratory group. In the pons, the pontine respiratory group includes two areas known as the pneumotaxic centre and the apneustic centre.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Diencephalon, Option: B. Midbrain, and Option: D. Spinal cord Diencephalon, midbrain and spinal cord are not known to contain pneumotaxic or apneustic centres.</p>\n<p><strong>Extraedge:</strong></p><p>The pneumotaxic centre is located in the upper part of the pons. Its nuclei are the sub-parabrachial nucleus and the medial parabrachial nucleus. The pneumotaxic centre controls both the rate and the pattern of breathing. The pneumotaxic centre is considered an antagonist to the apneustic centre. The pneumotaxic centre is responsible for limiting inspiration and providing an inspiratory off-switch (IOS). It limits the burst of action potentials in the phrenic nerve, effectively decreasing the tidal volume and regulating the respiratory rate. The absence of the centre results in an increase in the depth of respiration and a decrease in respiratory rate. The apneustic centre of the lower pons appears to promote inhalation by constant stimulation of the neurons in the medulla oblongata. The apneustic centre sends signals to the dorsal group in the medulla to delay the 'switch off', the inspiratory off switch (IOS) signal of the inspiratory ramp provided by the pneumotaxic centre. It controls the intensity of breathing, giving positive impulses to the neurons involved with inhalation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Fibres passing through crus cerebri are:", "options": [{"label": "A", "text": "Corticonuclear and corticospinal fibers", "correct": true}, {"label": "B", "text": "Medial lemniscus", "correct": false}, {"label": "C", "text": "Spinothalamic", "correct": false}, {"label": "D", "text": "All", "correct": false}], "correct_answer": "A. Corticonuclear and corticospinal fibers", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Corticonuclear and corticospinal fibers Corticonuclear and corticospinal fibres pass through crus cerebri.</p>\n<p><strong>Highyeild:</strong></p><p>The crus cerebri (cerebral crus) usually refers to the most anterior, semilunar-shaped bundle of white matter fibres in the midbrain, including the corticospinal tract centrally (3/5 intermediates) as well as the corticopontine (fronto-pontine and temporal-pontine fibres) and corticobulbar tracts. Posterior to the crus cerebri is the substantia nigra, followed by the mesencephalic tegmentum. Cross-section of the midbrain at the level of the inferior colliculi. NOTE: corticonuclear fibres are also known as corticobulbar</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Medial lemniscus M edial lemniscus , also known as Reil's band or Reil's ribbon , is a large ascending bundle of heavily myelinated axons that decussate (cross) in the brainstem, specifically in the medulla oblongata. The medial lemniscus is formed by the crossings of the internal arcuate fibres. The internal arcuate fibres are composed of axons of the nucleus gracilis and nucleus cuneatus. The axons of the nucleus gracilis and nucleus cuneatus in the medial lemniscus have cell bodies that lie contralaterally. Option: C. Spinothalamic The spinothalamic tract is a part of the anterolateral system or the ventrolateral system , a sensory pathway to the thalamus. From the ventral posterolateral nucleus in the thalamus, sensory information is relayed upward to the somatosensory cortex of the postcentral gyrus. The spinothalamic tract consists of two adjacent pathways: anterior and lateral. The anterior spinothalamic tract carries information about crude touch. The lateral spinothalamic tract conveys pain and temperature. The axons of the tract cells cross over (decussate) to the other side of the spinal cord via the anterior white commissure, and to the anterolateral corner of the spinal cord (hence the spinothalamic tract being part of the anterolateral system). Decussation usually occurs in 1-2 spinal nerve segments above the point of entry. The axons travel up the length of the spinal cord into the brainstem, specifically the rostral ventromedial medulla. Option: D. All Corticonuclear and corticospinal fibres pass through the crus cerebri of the midbrain so all of the above is incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>The cerebral peduncles are the anterior part of the midbrain that connects the remainder of the brainstem to the thalami. They are paired, separated by the interpeduncular cistern, and contain the large white matter tracts that run to and from the cerebrum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Interpeduncular fossa contains all, except:", "options": [{"label": "A", "text": "Mammillary Bodies", "correct": false}, {"label": "B", "text": "Posterior perforated substance", "correct": false}, {"label": "C", "text": "Oculomotor nerve", "correct": false}, {"label": "D", "text": "Ophthalmic nerve", "correct": true}], "correct_answer": "D. Ophthalmic nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ophthalmic nerve Contents of the interpeduncular fossa are posterior perforated substance, mammillary body, tuber cinereum, infundibulum, Pituitary Gland, oculomotor nerve, and circle of Willis.</p>\n<p><strong>Highyeild:</strong></p><p>Boundaries of Interpeduncular fossa The interpeduncular fossa is in front by the optic chiasma, behind by the anterosuperior surface of the pons, anterolaterally by the converging optic tracts, and posterolaterally by the diverging cerebral peduncles. The floor of the interpeduncular fossa, from behind forward, is the posterior perforated substance,corpora mamillaria, tuber cinereum, infundibulum, and pituitary gland. Interpeduncular fossa</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Mammillary Bodies Contents of the interpeduncular fossa are posterior perforated substance, mammillary body, tuber cinereum, infundibulum, Pituitary Gland, oculomotor nerve, and circle of Willis Option: B. Posterior perforated substance The floor of the interpeduncular fossa, from behind forward, is the posterior perforated substance, corpora mamillaria, tuber cinereum, infundibulum, and pituitary gland. Option:C. Oculomotor nerve Contents of the interpeduncular fossa include the oculomotor nerve and the circle of Willis.</p>\n<p><strong>Extraedge:</strong></p><p>The most common locations for neurocutaneous melanosis have occurred along the interpeduncular fossa, ventral brainstem, upper cervical cord, and ventral lumbosacral cord.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Olive is seen in which part of the brain:", "options": [{"label": "A", "text": "Medulla", "correct": true}, {"label": "B", "text": "Cerebellum", "correct": false}, {"label": "C", "text": "Midbrain", "correct": false}, {"label": "D", "text": "Pons", "correct": false}], "correct_answer": "A. Medulla", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Medulla Olive is in the ventral part of the This elevation is formed because of an inferior olivary nucleus. Ventral aspect of the brainstem</p>\n<p><strong>Highyeild:</strong></p><p>The olivary body is located on the anterior surface of the medulla lateral to the pyramid, from which it is separated by the anterolateral sulcus and the fibres of the hypoglossal nerve. Behind (dorsally), it is separated from the postero-lateral sulcus by the ventral spinocerebellar fasciculus. In the depression between the upper end of the olive and the pons lies the vestibulocochlear nerve. In humans, it measures about 1.25 cm. in length, and between its upper end and the pons, there is a slight depression to which the roots of the facial nerve are attached. The olive consists of two parts: The inferior olivary nucleus (or 'complex'), is a part of the Olivo-cerebellar system and is mainly involved in cerebellar motor learning and function. The superior olivary nucleus, considered part of the pons and part of the auditory system, aids the perception of sound.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Cerebellum Olive is in the ventral part of the This elevation is formed because of an inferior olivary nucleus. Option: C. Midbrain Olive is in the ventral part of the This elevation is formed because of an inferior olivary nucleus. Option: D. Pons Olive is in the ventral part of the This elevation is formed because of an inferior olivary nucleus.</p>\n<p><strong>Extraedge:</strong></p><p>The lateral wall of the interpeduncular fossa bears a groove - the oculomotor sulcus - from which rootlets of the oculomotor nerve emerge from the substance of the brainstem and aggregate into a single fascicle. The ventral tegmental area lies at the depth of the interpeduncular fossa.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Facial colliculus is seen in:", "options": [{"label": "A", "text": "Midbrain", "correct": false}, {"label": "B", "text": "Pons", "correct": true}, {"label": "C", "text": "Medulla", "correct": false}, {"label": "D", "text": "Interpeduncular fossa", "correct": false}], "correct_answer": "B. Pons", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pons The facial colliculus is an elevated area located in the pontine tegmentum (dorsal pons), within the floor of the fourth ventricle (i.e. the rhomboid fossa). It is formed by fibres from the facial motor nucleus looping over the abducens nucleus. The facial colliculus is an essential landmark of the rhomboid fossa. Transverse section of Pons at the level of Facial Colliculus</p>\n<p><strong>Highyeild:</strong></p><p>The facial colliculus is formed by branchial motor nerve fibres of the facial nerve (CN VII) looping over the (ipsilateral) abducens nucleus, forming a bump upon the surface.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Midbrain Option: B. Pons Option: C. Medulla Option: A, B and C. are incorrect answers because the F acial colliculus is an elevated area located in the pontine tegmentum (dorsal pons), within the floor of the fourth ventricle.</p>\n<p><strong>Extraedge:</strong></p><p>A facial colliculus lesion would result in ipsilateral facial paralysis (i.e. Bell's palsy) and inhibited ipsilateral and unopposed contralateral eye deviation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Injury to which of the following nerve will lead to ipsilateral convergent squint?", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": true}], "correct_answer": "D. D", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391863585-QTDA055008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>D</p>\n<p><strong>Highyeild:</strong></p><p>Oculomotor nerve palsy or oculomotor neuropathy is an eye condition resulting from damage to the third cranial nerve. The oculomotor nerve supplies the majority of the muscles controlling eye movements (four of the six extraocular muscles, excluding only the lateral rectus and superior oblique). Damage to this nerve will result in an inability to move the eye normally. The nerve also supplies the upper eyelid muscle (levator palpebrae superioris) and is accompanied by parasympathetic fibres innervating the muscles responsible for pupil constriction (sphincter pupillae). The limitations of eye movement resulting from the condition are generally so severe that patients are often unable to maintain normal eye alignment when gazing straight ahead, leading to strabismus and, as a consequence, double vision (diplopia).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. A A is an oculomotor nerve A complete oculomotor nerve palsy will result in a characteristic displacement outward (exotropia) and downward (hypotropia). The outward displacement occurs because the lateral rectus muscle (innervated by the sixth cranial nerve) maintains muscle tone in comparison to the paralyzed medial rectus. The downward displacement occurs because the superior oblique muscle (innervated by the fourth cranial or trochlear nerve) is unantagonized by the paralyzed superior rectus, inferior rectus and inferior oblique. The affected individual will also have ptosis, drooping of the eyelid, and mydriasis (pupil dilation). Option: B. B B is trochlear nerve Injury to the trochlear nerve causes weakness of downward eye movement with consequent vertical diplopia (double vision). The affected eye drifts upward relative to the normal eye, due to the unopposed actions of the remaining extraocular muscles. Option: C. C C is trigeminal nerve The trigeminal nerve does not innervate extraocular muscles.</p>\n<p><strong>Extraedge:</strong></p><p>Oculomotor palsy can arise as a result of a number of different conditions. Non-traumatic pupil-sparing oculomotor nerve palsies are often referred to as a \"medical third\", with those affecting the pupil being known as a \"surgical third\".</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not concerned with the auditory pathway?", "options": [{"label": "A", "text": "Trapezoid Body", "correct": false}, {"label": "B", "text": "Medial geniculate body", "correct": false}, {"label": "C", "text": "Lateral geniculate body", "correct": true}, {"label": "D", "text": "Lateral lemniscus", "correct": false}], "correct_answer": "C. Lateral geniculate body", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral geniculate body The lateral geniculate nucleus (LGN) belongs to the category of sensory projection nuclei of the thalamus and plays an essential role in normal visual processing.</p>\n<p><strong>Highyeild:</strong></p><p>Auditory pathway The auditory pathway conveys the special sense of hearing. Information travels from the receptors in the organ of Corti of the inner ear (cochlear hair cells) to the central nervous system, carried by the vestibulocochlear nerve (CN VIII). The auditory nerve transmits auditory information up a series of nuclei to the cortex where perception occurs. These nuclei include Cochlear nucleus, Superior olivary nuclei, Lateral lemniscus, Inferior colliculus, and Medial geniculate nuclei. Auditory pathway</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Trapezoid Body Option: B. Medial geniculate body Option: D. Lateral lemniscus The Trapezoid body, MGB and Lateral lemniscus all are related to the auditory pathway.</p>\n<p><strong>Extraedge:</strong></p><p>The auditory pathway is complex in that divergence and convergence of information happen at different stages. There are two main components of the auditory pathway: Primary (lemniscal) pathway – this is the main pathway through which auditory information reaches the primary auditory cortex (A1). Non-lemniscal pathway – mediating unconscious perception such as attention, emotional response, and auditory reflexes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following tract of fibres is primarily involved in correlating movements of the eyes with signals from vestibular nuclei?", "options": [{"label": "A", "text": "Medial Lemniscus", "correct": false}, {"label": "B", "text": "Lateral lemniscus", "correct": false}, {"label": "C", "text": "Medial longitudinal fasciculus", "correct": true}, {"label": "D", "text": "Dorsal longitudinal fasciculus", "correct": false}], "correct_answer": "C. Medial longitudinal fasciculus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Medial longitudinal fasciculus Medial longitudinal fasciculus-co-ordinate the movements of the eye, head, and neck in response to VIII cranial nerve Heavily myelinated tract in the paramedian position of the brain stem MLF interconnect-III, IV, VI, spinal part of XI with Vill nuclei</p>\n<p><strong>Highyeild:</strong></p><p>The medial longitudinal fasciculus (MLF) is an area of crossed-over tracts, on each side of the brainstem. These bundles of axons are situated near the midline of the brainstem. They are made up of both ascending and descending fibres that arise from a number of sources and terminate in different areas, including the superior colliculus, the vestibular nuclei, and the cerebellum. It contains the interstitial nucleus of the Cajal, responsible for oculomotor control, head posture, and vertical eye movement. Medial longitudinal fasciculus (MLF)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Medial Lemniscus The medial lemniscus is part of the dorsal column–medial lemniscus pathway, which ascends from the skin to the thalamus, which is important for somatosensation from the skin and joints, therefore, lesion of the medial lemnisci causes impairment of vibratory and touch-pressure sense. Option: B. Lateral lemniscus The lateral lemniscus is part of the auditory tract of the brainstem. It starts at the level of the superior olivary complex and terminates at the inferior colliculus. The fibres of the contralateral dorsal cochlear nucleus reach the central nucleus of the inferior colliculus directly via the lateral lemniscus. Option: D. Dorsal longitudinal fasciculus The dorsal longitudinal fasciculus (fasciculus of Schutz) is periaqueductal ascending and descending fibre system arising from the hypothalamus and terminating to the autonomic nuclei of the pons and the medulla, conveying autonomic fibres.</p>\n<p><strong>Extraedge:</strong></p><p>The medial longitudinal fasciculus is the main central connection for the oculomotor nerve, trochlear nerve, and abducens nerve . It carries information about the direction that the eyes should move. Lesions of the medial longitudinal fasciculus can cause nystagmus and diplopia, which may be associated with multiple sclerosis, a neoplasm, or a stroke.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The position of the nucleus ambiguus is", "options": [{"label": "A", "text": "Anteromedial To Olive", "correct": false}, {"label": "B", "text": "Anterolateral to olive", "correct": false}, {"label": "C", "text": "Posteromedial to olive", "correct": false}, {"label": "D", "text": "Posterolateral to olive", "correct": true}], "correct_answer": "D. Posterolateral to olive", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterolateral to olive Nucleus ambiguus is a motor nucleus located in the upper medulla oblongata, posteromedial to olive. The nucleus ambiguus location is in the reticular formation of the medulla oblongata, the lowest part of the brainstem. The nuclei are in the lateral regions of the rostral medulla posterior to the inferior olive. The nucleus ambiguus is involved in the motor functions of swallowing and speech.</p>\n<p><strong>Highyeild:</strong></p><p>The nucleus ambiguus contains the cell bodies of neurons that innervate the muscles of the soft palate, pharynx, and larynx which are associated with speech and swallowing. As well as motor neurons, the nucleus ambiguus contains preganglionic parasympathetic neurons which innervate postganglionic parasympathetic neurons in the heart. This nucleus gives rise to the branchial efferent motor fibres of the vagus nerve (CN X) terminating in the laryngeal, pharyngeal muscles, and musculus uvulae as well as to the efferent motor fibres of the glossopharyngeal nerve (CN IX) terminating in the stylopharyngeus muscle. Nucleus ambiguus location in transverse section of Medulla</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Anteromedial To Olive Option: B. Anterolateral to olive Option: D. Posterolateral to olive Options A, B and D. are incorrect answers because Nucleus Ambiguus is located posteromedial to Olive.</p>\n<p><strong>Extraedge:</strong></p><p>The nucleus ambiguus controls the motor innervation of ipsilateral muscles of the soft palate, pharynx, larynx and upper esophagus. Lesions of nucleus ambiguus result in nasal speech, dysphagia, dysphonia, and deviation of the uvula toward the contralateral side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 68-year-old woman presents in the emergency room with dizziness and nystagmus. Examination reveals a loss of pain and temperature sensation over the right side of the face and the left side of the body. The patient exhibits ataxia and intention tremors in both the upper and lower extremities on the right side and is unable to perform either the finger-to-nose or heel-to-shin tasks from the right limbs. In addition, she has hoarseness of voice and demonstrates pupillary constriction and drooping of the right eyelid. Also, the right side of her face is drier than the left. Blockage of which of the following arteries would explain the patient's condition?", "options": [{"label": "A", "text": "Right posterior inferior cerebellar artery", "correct": true}, {"label": "B", "text": "Left posterior inferior cerebellar artery", "correct": false}, {"label": "C", "text": "Right anterior inferior cerebellar artery", "correct": false}, {"label": "D", "text": "Basilar artery", "correct": false}], "correct_answer": "A. Right posterior inferior cerebellar artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right posterior inferior cerebellar artery This is a case of right-sided Wallenberg syndrome due to occlusion in the right posterior inferior cerebellar artery, leading to lateral medullary ischaemia and lesion of certain nuclei and tracts. Wallenberg syndrome is also known as PICA syndrome but the most commonly involved vessel is the vertebral artery. The patient has alternating hemi-anaesthesia: ipsilateral loss of pain and temperature on the face and contralateral loss of pain and temperature on the body. It occurs due to a lesion of the lateral spinothalamic tract and the spinal sensory nucleus of the trigeminal nerve. Ataxia and intention tremors indicate injury to the spinocerebellar tract in the lateral medulla There is hoarseness of voice which indicates a lesion of the nucleus ambiguus (which controls muscles of the larynx) The patient also has features of right-sided Horner syndrome due to a lesion of the hypothalamic-spinal pathway in the lateral medulla</p>\n<p><strong>Highyeild:</strong></p><p>Lateral medullary/Wallenberg syndrome: Occurs due to blockage of a posterior inferior cerebellar artery. It supplies areas behind the inferior olivary nucleus. Features are Ipsilateral paralysis of most muscles of the soft palate, pharynx and larynx due to injury to the nucleus ambiguus which gives fibres to IX, X and XI cranial nerves. Loss of pain and temperature on the same side of the face due to the involvement of the spinal nucleus and spinal tract of the trigeminal nerve. Loss of pain and temperature on the opposite side of the body due to the involvement of the lateral spinothalamic tract. Giddiness due to involvement of vestibular nuclei. Damage to the inferior cerebellar peduncle, spinocerebellar tracts and part of the cerebellum results in loss of equilibrium, i.e. ataxia of limbs on the same side. The sympathetic fibres descend from the hypothalamus to cells in the lateral horn of the spinal cord. As these fibres descend in the lateral part of the medulla (which is damaged), there is Horner’s syndrome, comprising ptosis, enophthalmos, miosis and anhidrosis. Lesions of medulla oblongata: (1) Medial medullary syndrome; (2) Lateral medullary syndrome</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Left posterior inferior cerebellar artery In Wallenberg syndrome, there is loss of pain and temperature on the opposite side of the body due to the involvement of the lateral spinothalamic tract. In the above case, there is loss of pain and temperature in the left side of the body so the Right posterior inferior cerebellar artery is involved. Option: C. Right anterior inferior cerebellar artery Anterior inferior cerebellar artery (AICA) territory infarcts are much less common than posterior inferior cerebellar artery (PICA) infarcts. AICA generally arises from the caudal third of the basilar artery and supplies the lateral pons, inner ear, middle cerebellar peduncle and anterior inferior cerebellum. Vertigo (can be central or peripheral due to the arterial supply) is the most common symptom associated with an AICA infarct, however, it is normally associated with neurological signs and symptoms such as facial weakness, hypoacusis, facial sensory loss, crossed sensory loss, gait ataxia, limb ataxia and Horner’s syndrome. Option: D. Basilar artery Most commonly, patients experiencing basilar artery occlusion exhibit acute neurologic signs including motor deficits, hemiparesis or quadriparesis, facial palsies, dizziness, headache, and speech abnormalities–especially dysarthria and difficulty articulating words.</p>\n<p><strong>Extraedge:</strong></p><p>Medial medullary/Dejerine syndrome: It occurs due to blockage of the anterior spinal artery. Medial medullary syndrome Features are: Contralateral hemiplegia due to damage to the pyramid of the medulla. Loss of sense of vibration and position due to damage to the medial lemniscus. Paralysis of muscles of the tongue on the same side due to injury to XII cranial nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The final common pathway for horizontal gaze is the nucleus:", "options": [{"label": "A", "text": "Abducens", "correct": true}, {"label": "B", "text": "oculomotor", "correct": false}, {"label": "C", "text": "Pre-motor cortex", "correct": false}, {"label": "D", "text": "Primary somatosensory cortex", "correct": false}], "correct_answer": "A. Abducens", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Abducens The final common pathway for horizontal saccades is from the abducens nucleus complex (ANC), which contains neurons supplying the ipsilateral lateral rectus and abducens interneurons, fibres of which cross to the opposite side and ascend in the medial longitudinal fasciculus (MLF) to innervate the contralateral medial rectus muscle.</p>\n<p><strong>Highyeild:</strong></p><p>The subcortical centre for horizontal conjugate gaze lies in the abducens nucleus in the pons It receives input from the contralateral frontal eye field and controls the ipsilateral lateral rectus and contralateral the medial rectus muscle via projections of medial longitudinal fasciculus (MLF) MLF connects the nuclei controlling eyeball muscles and mediates nystagmus and lateral conjugate gaze Its fibres originate in the vestibular nucleus and terminate in abducent, trochlear and oculomotor nuclei It coordinates eyeball movements with the head. The trochlear nucleus is mainly concerned with vertical gaze movements.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. oculomotor Option: C. Premotor cortex Option: D. Primary somatosensory cortex Option: B, C and D. are incorrect answers because, the final common pathway for horizontal saccades is from the abducens nucleus complex (ANC), which contains neurons supplying the ipsilateral lateral rectus and abducens interneurons, fibres of which cross to the opposite side and ascend in the medial longitudinal fasciculus (MLF) to innervate the contralateral medial rectus muscle.</p>\n<p><strong>Extraedge:</strong></p><p>Horizontal gaze, the final common pathway for horizontal gaze lives in the pons, and that is mediated by the parapontine reticular formation and the sixth nerve nucleus. This is a horizontal pathway. The vertical pathway lives at the junction of the thalamus and the midbrain, the Thalamo mesencephalic junction.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about 4th ventricle:", "options": [{"label": "A", "text": "Rhomboid fossa forms the floor", "correct": true}, {"label": "B", "text": "Choroid plexus lies at its floor", "correct": false}, {"label": "C", "text": "Connection between two cerebral hemispheres", "correct": false}, {"label": "D", "text": "Lies inferior to inferior cerebellar peduncle", "correct": false}], "correct_answer": "A. Rhomboid fossa forms the floor", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Rhomboid fossa forms the floor The floor of the 4th Ventricle: It is also called 'rhomboid fossa' because of its rhomboidal shape. The floor is formed by: 1 Posterior (dorsal) surface of the lower or closed part of the 2 Posterior (dorsal) surface of the open or upper part of the medulla oblongata.</p>\n<p><strong>Highyeild:</strong></p><p>The fourth ventricle is one of the four connected fluid-filled cavities within the human brain. These cavities, known collectively as the ventricular system, consist of the left and right lateral ventricles, the third ventricle, and the fourth ventricle. The fourth ventricle extends from the cerebral aqueduct ( aqueduct of Sylvius ) to the obex and is filled with cerebrospinal fluid (CSF). The fourth ventricle has a characteristic diamond shape in cross-sections of the human brain. It is located within the pons or in the upper part of the medulla oblongata. CSF entering the fourth ventricle through the cerebral aqueduct can exit the subarachnoid space of the spinal cord through two lateral apertures and a single, midline median aperture. Fourth ventricle floor</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Choroid plexus lies at its floor Option: C. Connection between two cerebral hemispheres Option: D. Lies inferior to inferior cerebellar peduncle Choroid plexuses of the 4 Ventricle: The capillary plexus of blood vessels between the two layers of tela choroidea form the rich vascular fringe that projects through the lower part of the roof of the fourth ventricle to form the choroid plexus. It is derived from the branches of the posterior inferior cerebellar arteries. The plexus projects into the cavity through the lower part of the roof. The connection between the cerebral hemispheres is via the lateral ventricle. Cerebellar peduncles lie on the lateral wall of the 4th ventricle.</p>\n<p><strong>Extraedge:</strong></p><p>The ventricular system, including the fourth ventricle, develops from the central canal of the neural tube. Specifically, the fourth ventricle originates from the portion of the tube that is present in the developing rhombencephalon.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which nucleus is not found in the floor of the fourth ventricle:", "options": [{"label": "A", "text": "Abducens Nucleus", "correct": false}, {"label": "B", "text": "Dorsal nucleus of the vagus", "correct": false}, {"label": "C", "text": "Hypoglossal nucleus", "correct": false}, {"label": "D", "text": "None", "correct": true}], "correct_answer": "D. None", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>None The Abducens Nucleus, Dorsal nucleus of the vagus and Hypoglossal nucleus are all present on the floor of the IV ventricle.</p>\n<p><strong>Highyeild:</strong></p><p>Features of the Floor of the 4th Ventricle: The dorsal median sulcus divides the floor into two symmetrical halves. Sulcus limitans divide each half into median eminence and lateral vestibular area. The sulcus limitans present depression at the cranial end called the superior fovea and towards the caudal part called the inferior fovea. Medial eminence: The eminence is wider above and narrow below. It presents facial colliculus just opposite and medial to the superior fovea. Deep to the colliculus is the genu of the facial nerve formed by this nerve looping around the abducens nucleus. In the uppermost part (pontine part), the sulcus limitans overlies an area that is bluish in colour and is called locus coeruleus . The colour is due to the presence of pigmented neurons which constitute substantia ferruginea. These neurons belong to the reticular formation. They are rich in noradrenaline and help in paradoxical sleep. Descending from the inferior fovea, there is a sulcus that runs obliquely towards the This sulcus divides the medial eminence into two triangles. These are the hypoglossal triangle medially and the the vagal triangle laterally . These overlie the hypoglossal nerve nucleus and the vagus nerve, respectively. Between the vagal triangle above and the gracile tubercle below, there is a small area called the area postrema which may function as a chemoreceptor. An ependymal thickening called funiculus separans separates both. This area is devoid of the blood-brain barrier. Vestibular area : This lies lateral to the inferior fovea (sulcus limitans) which overlies the vestibular nuclei. This area is partly in the pons and partly in the medulla. Fourth ventricle floor</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Abducens Nucleus Option: B. Dorsal nucleus of the vagus Option: C. Hypoglossal nucleus Abducens Nucleus, Dorsal nucleus of the vagus and Hypoglossal nucleus are all present in the floor of the IV ventricle, therefore options A, B and C are the incorrect answer.</p>\n<p><strong>Extraedge:</strong></p><p>The lowest part of the floor of the fourth ventricle resembles the pointed nib of the writing pen so it is described as calamus scriptorius.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Damage to the structure producing the arrow-marked elevation leads to paralysis of which of the following muscle?", "options": [{"label": "A", "text": "Lateral Rectus", "correct": false}, {"label": "B", "text": "Risorius", "correct": true}, {"label": "C", "text": "Levator palpebrae superioris", "correct": false}, {"label": "D", "text": "Superior oblique", "correct": false}], "correct_answer": "B. Risorius", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391865904-QTDA055016IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Risorius Key-marked structure - facial colliculus. Facial colliculus is a rounded elevation formed by the axons of the facial nerve (and not by the abducens nucleus deep to it) Damage to the axons of the facial nerve causes paralysis of muscles of facial expression like risorius.</p>\n<p><strong>Highyeild:</strong></p><p>The facial colliculus is an elevated area located in the pontine tegmentum (dorsal pons), within the floor of the fourth ventricle (i.e. the rhomboid fossa). It is formed by fibres from the facial motor nucleus looping over the abducens nucleus. The facial colliculus is an essential landmark of the rhomboid fossa.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Lateral Rectus The lateral rectus is supplied by the abducens cranial nerve, if the injury is deeper and more severe it can involve both the facial and abducens nerve nucleus. Option: C. Levator palpebrae superioris Levator palpebrae superioris is innervated by oculomotor nerve. Option: D. Superior oblique The superior oblique is innervated by the trochlear nerve.</p>\n<p><strong>Extraedge:</strong></p><p>A facial colliculus lesion would result in ipsilateral facial paralysis (i.e. Bell's palsy) and inhibited ipsilateral and unopposed contralateral eye deviation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following clinical manifestations is not seen in the lesion depicted by the image?", "options": [{"label": "A", "text": "Ipsilateral flaccid paralysis of the medial rectus", "correct": false}, {"label": "B", "text": "Contralateral hemiplegia", "correct": false}, {"label": "C", "text": "Contralateral weakness of the lower face", "correct": false}, {"label": "D", "text": "Ipsilateral loss of pain and temperature from the face", "correct": true}], "correct_answer": "D. Ipsilateral loss of pain and temperature from the face", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391866893-QTDA055017IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ipsilateral loss of pain and temperature from the face The Syndrome indicated in the image above is Weber’s syndrome of the midbrain involving the III nerve, pyramidal tract, and Corticonuclear fibres. Ipsilateral loss of pain and temperature from the face occurs in the lesion of the spinal nucleus of the V nerve, which is located in the medulla oblongata.</p>\n<p><strong>Highyeild:</strong></p><p>Weber’s syndrome: This syndrome involves the III nerve nucleus and corticospinal fibres. Features are Hemiplegia on the opposite side due to involvement of corticospinal fibres. The pupil points downwards and laterally due to paralysis of the III nerve. Benedikt’s syndrome : In this condition, most of the tegmentum of the midbrain is damaged. Lesion includes loss of medial lemniscus, red nucleus, superior cerebellar peduncle and fibres of III nerve. Features are Loss of proprioception due to a lesion of the medial lemniscus. The pupil points downwards and laterally due to injury to the III nerve. Tremors and twitching of the opposite side due to damage to the red nucleus and superior cerebellar peduncle. Parinaud’s syndrome : Lesion of superior colliculi leads to this syndrome. Features include weakness of upward gaze and vertical nystagmus due to a lesion of the superior colliculus. Argyll Robertson pupil : In this condition, the light reflex is lost but the accommodation reflex is retained due to a lesion in the vicinity of the pretectal nucleus Lesion of Midbrain</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Ipsilateral flaccid paralysis of the medial rectus Option: B. Contralateral hemiplegia Option: C. Contralateral weakness of the lower face All the above symptoms are present in Weber syndrome.</p>\n<p><strong>Extraedge:</strong></p><p>Weber's syndrome, also known as midbrain stroke syndrome or superior alternating hemiplegia , is a form of stroke that affects the medial portion of the midbrain. It involves oculomotor fascicles in the interpeduncular cisterns and cerebral peduncle so it characterizes the presence of an ipsilateral lower motor neuron type oculomotor nerve palsy and contralateral hemiparesis or hemiplegia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 27 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which of the following diseases primarily involves the marked structure?", "options": [{"label": "A", "text": "Depression", "correct": false}, {"label": "B", "text": "Alzheimer's", "correct": false}, {"label": "C", "text": "Paralysis agitans", "correct": true}, {"label": "D", "text": "Huntington's chorea", "correct": false}], "correct_answer": "C. Paralysis agitans", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759707453-QTDA056001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Paralysis agitans Marked structure - substantia nigra- Parkinson’s (paralysis agitans) Parkinson's disease is a slowly progressive disorder that affects movement, muscle control, and balance. Part of the disease process develops as cells are destroyed in certain parts of the brain stem, particularly the crescent-shaped cell mass known as the substantia nigra. Nerve cells in the substantia nigra send out fibers to tissue located on both sides of the brain. There the cells release essential neurotransmitters that help control movement and coordination. Parts of Midbrain</p>\n<p><strong>Highyeild:</strong></p><p>The substantia nigra (SN) is a basal ganglia structure located in the midbrain that plays an important role in reward and movement. Substantia nigra means \"black substance\", reflecting the fact that parts of the substantia nigra appear darker than neighboring areas due to high levels of neuromelanin in dopaminergic neurons. Parkinson's disease is characterized by the loss of dopaminergic neurons in the substantia nigra pars compacta.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Depression According to researchers, Depression causes are due to specific brain chemicals — nerve cell connections, nerve cell growth, and the functioning of nerve circuits having a major impact on depression. Option: B. Alzheimer's In the Alzheimer's brain, abnormal levels of this naturally occurring protein clump together to form plaques that collect between neurons and disrupt cell function. It is formed from the breakdown of a larger protein, called amyloid precursor protein. One form, beta-amyloid 42, is thought to be especially toxic. Option: D. Huntington's chorea Huntington's chorea disease attacks areas of the brain that help to control voluntary (intentional) movement, as well as other areas. People living with HD develop uncontrollable dance-like movements (chorea) and abnormal body postures, as well as problems with behavior, emotion, thinking, and personality.</p>\n<p><strong>Extraedge:</strong></p><p>The substantia nigra, along with four other nuclei, is part of the basal ganglia. It is the largest nucleus in the midbrain, lying dorsal to the cerebral peduncles. The SN is divided into two parts: the pars reticulata (SNpr) and the pars compacta (SNpc), which lies medial to the pars reticulata. Sometimes, a third region, the pars lateralis, is mentioned, though it is usually classified as part of the pars reticulata. The (SNpr) and the internal globus pallidus (GPi) are separated by the internal capsule .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45 year old male patient presented to you in the emergency department with left-sided hemiplegia. On careful examination, you have found the following abnormality in his right eye. Which of the following is the most likely diagnosis of the patient?", "options": [{"label": "A", "text": "Benedikt Syndrome", "correct": false}, {"label": "B", "text": "Weber syndrome", "correct": true}, {"label": "C", "text": "Wallenberg syndrome", "correct": false}, {"label": "D", "text": "Medial medullary syndrome", "correct": false}], "correct_answer": "B. Weber syndrome", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759707557-QTDA056002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Weber syndrome Weber syndrome, classically described as a midbrain stroke syndrome involves oculomotor fascicles in the interpeduncular cisterns and cerebral peduncle, thereby causing ipsilateral third nerve palsy with contralateral hemiparesis. The above image shows a down-and-out eye suggestive of 3rd cranial nerve palsy.</p>\n<p><strong>Highyeild:</strong></p><p>Weber's syndrome, also known as midbrain stroke syndrome or superior alternating hemiplegia, is a form of stroke that affects the medial portion of the midbrain. It involves oculomotor fascicles in the interpeduncular cisterns and cerebral peduncle so it characterizes the presence of an ipsilateral lower motor neuron type oculomotor nerve palsy and contralateral hemiparesis or hemiplegia. Weber syndrome</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Benedikt syndrome - there is no motor weakness in Benedikt's syndrome. It is characterised by ipsilateral 3rd nerve palsy and contralateral hemi tremors due to the involvement of the red nucleus. Option: C and D. Wallenberg syndrome and medial medullary syndrome do not involve the oculomotor nerve.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical findings of Weber's syndrome are, mainly the eyeball is down and out ipsilateral lateral squint. Ptosis presents as the levator palpebrae superioris nerve supply is disrupted. The pupil dilated and fixed. Contralateral hemiplegia CT scan or MRI might help in delineating the cause of the vessel or region of the brain involved in the stroke</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In the given image identify the area involved in Benedikt’s syndrome –", "options": [{"label": "A", "text": "1", "correct": false}, {"label": "B", "text": "2", "correct": true}, {"label": "C", "text": "3", "correct": false}, {"label": "D", "text": "4", "correct": false}], "correct_answer": "B. 2", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759707616-QTDA056003IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2 Benedikt's syndrome Benedikt's syndrome occurs due to the vascular ischaemia of the tegmentum of the midbrain involving the medial lemniscus, spinal lemniscus, red nucleus, superior cerebellar peduncle and fibres of the oculomotor nerve. It is characterized by the following signs and symptoms: Oculomotor nerve palsy: eyeball gazing downward and outward position, diplopia, miosis, mydriasis, and loss of accommodation reflex. Contralateral loss of proprioception and vibration sensations. Cerebellar ataxia: involuntary movements. Benedikt's syndrome</p>\n<p><strong>Highyeild:</strong></p><p>Benedikt syndrome, also called Benedikt's syndrome or paramedian midbrain syndrome, is a rare type of posterior circulation stroke of the brain, with a range of neurological symptoms affecting the midbrain, cerebellum and other related structures. It is characterized by the presence of an oculomotor nerve (CN III) palsy and cerebellar ataxia including tremors and involuntary choreoathetotic movements. Neuroanatomical structures affected include the oculomotor nucleus, red nucleus, corticospinal tracts and superior cerebellar peduncle decussation. It has a similar cause, morphology, signs and symptoms to Weber's syndrome; the main difference between the two is that Weber's is more associated with hemiplegia (i.e. paralysis), and Benedikt's with hemiataxia (i.e. disturbed coordination of movements)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. 1 Area 1 is involved in Weber's syndrome. Option: C. 3 Area 3 is involved in Parinaud’s syndrome. Option: D. 4 Area 4 is involved in Argyll Robertson pupils.</p>\n<p><strong>Extraedge:</strong></p><p>Benedikt's syndrome is also similar to Claude's syndrome but is distinguishable by the fact that, Benedikt's has more predominant tremor and choreoathetotic movements while Claude's is more marked by the ataxia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Arrange the following structures present in the midbrain from medially to laterally – Medial lemniscus Trigeminal lemniscus Spinal lemniscus Lateral lemniscus Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1 2 3 4", "correct": true}, {"label": "B", "text": "1 3 2 4", "correct": false}, {"label": "C", "text": "1 4 2 3", "correct": false}, {"label": "D", "text": "2 3 1 4", "correct": false}], "correct_answer": "A. 1 2 3 4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1 2 3 4 The arrangement of structures from medial to lateral in the midbrain are following: Medial lemniscus Trigeminal lemniscus Spinal lemniscus Lateral lemniscus</p>\n<p><strong>Highyeild:</strong></p><p>The trigeminal lemniscus, also called the trigeminothalamic tract, is composed of the ventral trigeminal tract, and the dorsal trigeminal tract – nerve tracts that convey tactile, pain, and temperature impulses from the skin of the face, the mucous membranes of the nasal and oral cavities, and the eye, as well as proprioceptive information from the facial and masticatory muscles. The trigeminal lemniscus is composed of second-order neuronal axons in the brainstem. It carries sensory information from the trigeminal system to the ventral posteromedial (VPM) nucleus of the thalamus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. 1 3 2 4 Option: C. 1 4 2 3 Option: D. 2 3 1 4 The arrangement of structures from medial to lateral in the midbrain is following: Medial lemniscus Trigeminal lemniscus Spinal lemniscus Lateral lemniscus Therefore Options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The spinothalamic tract is a part of the anterolateral system or the ventrolateral system , a sensory pathway to the thalamus. From the ventral posterolateral nucleus in the thalamus, sensory information is relayed upward to the somatosensory cortex of the postcentral gyrus. The spinothalamic tract consists of two adjacent pathways: anterior and lateral. The anterior spinothalamic tract carries information about crude touch. The lateral spinothalamic tract conveys pain and temperature.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient presented to your outpatient department unable to perform the action in the given image. Which of the following can be the likely diagnosis?", "options": [{"label": "A", "text": "Benedikt Syndrome", "correct": false}, {"label": "B", "text": "Weber syndrome", "correct": false}, {"label": "C", "text": "Wallenberg syndrome", "correct": false}, {"label": "D", "text": "Parinaud syndrome", "correct": true}], "correct_answer": "D. Parinaud syndrome", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759707783-QTDA056005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Parinaud syndrome Parinaud syndrome is defined as a constellation of upward gaze palsy, convergence retraction nystagmus, light-near dissociation, and bilateral lid retraction.</p>\n<p><strong>Highyeild:</strong></p><p>Parinaud’s syndrome is defined as a constellation of upward gaze palsy, convergence retraction nystagmus, light-near dissociation, and bilateral lid retraction. It is caused by a lesion of the superior colliculus. Parinaud’s syndrome</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - Benedikts syndrome - Benedikt's syndrome (Fig. 25.14): In this condition, most of the tegmentum of midbrain is damaged. Lesion includes loss of medial lemniscus, red nucleus, superior cerebellar peduncle and fibres of III nerve. Features are: Loss of proprioception due to lesion of medial lemniscus. Pupil points downwards and laterally due to injury to III nerve. Tremors and twitching of opposite side due to damage to red nucleus and superior cerebellar peduncle. Option B -Weber syndrome - Weber syndrome, classically described as a midbrain stroke syndrome and superior alternating hemiplegia , involves oculomotor fascicles in the interpeduncular cisterns and cerebral peduncle, thereby causing ipsilateral third nerve palsy with contralateral hemiparesis. Option C - Wallenberg syndrome Lateral medullary syndrome is a neurological disorder causing a range of symptoms due to ischemia in the lateral part of the medulla oblongata in the brainstem. The ischemia is a result of a blockage most commonly in the vertebral artery or the posterior inferior cerebellar artery. Option: A - Benedikts syndrome - Benedikt's syndrome (Fig. 25.14): In this condition, most of the tegmentum of the midbrain is damaged. Lesion includes loss of medial lemniscus, red nucleus, superior cerebellar peduncle and fibres of III nerve. Features are: Loss of proprioception due to a lesion of the medial lemniscus. The pupil points downwards and laterally due to injury to the III nerve. Tremors and twitching of opposite side due to damage to the red nucleus and superior cerebellar peduncle. Option: B-Weber syndrome - Weber syndrome, classically described as a midbrain stroke syndrome and superior alternating hemiplegia, involves oculomotor fascicles in the interpeduncular cisterns and cerebral peduncle, thereby causing ipsilateral third nerve palsy with contralateral hemiparesis. Option: C - Wallenberg syndrome Lateral medullary syndrome is a neurological disorder causing a range of symptoms due to ischemia in the lateral part of the medulla oblongata in the brainstem. The ischemia is a result of a blockage most commonly in the vertebral artery or the posterior inferior cerebellar artery.</p>\n<p><strong>Extraedge:</strong></p><p>Parinaud’s syndrome is classically described by the triad of upgaze palsy, convergence retraction nystagmus, and pupillary hyporeflexia . Patients may complain of difficulty looking up, blurred near vision, diplopia, and oscillopsia, and there may be associated neurological symptoms.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 55 yr old male patient presented to your department with the following facial features. His right eye shows a convergent squint and there is also left-sided hemiparesis. Your senior tells you that this is a case of specific brainstem syndrome affecting the pons. Identify the syndrome.", "options": [{"label": "A", "text": "Wallenberg Syndrome", "correct": false}, {"label": "B", "text": "Millard gubler syndrome", "correct": true}, {"label": "C", "text": "Parinaud’s syndrome", "correct": false}, {"label": "D", "text": "Weber syndrome", "correct": false}], "correct_answer": "B. Millard gubler syndrome", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759707845-QTDA056006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Millard gubler syndrome Millard-Gubler syndrome (MGS), also known as facial abducens hemiplegia syndrome or ventral pontine syndrome, is one of the classical crossed brainstem syndromes characterized by a unilateral lesion of the basal portion of the caudal pons involving abducens (VI) and the facial (VII) cranial nerves and the pyramidal tract fibers. The diagnosis of Millard-Gubler syndrome is confirmed by clinical examination of cranial nerves VI and VII along with hemiplegia of the upper and lower extremities. Millard-Gubler syndrome (MGS)</p>\n<p><strong>Highyeild:</strong></p><p>Components of Millard-Gubler syndrome (MGS) Ipsilateral weakness of the eye on abduction (VI nerve) Ipsilateral facial muscle weakness (VII nerve) Contralateral hemiparesis or hemiplegia of upper and lower extremities (pyramidal tract involvement) MGS often presents with other neurological deficits such as contralateral hemiparesthesia and contralateral cerebellar ataxia as many other nuclei fibers exist near the root fibers of the facial nerve nucleus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Wallenberg syndrome is characterised by the lateral medullary syndrome. Option: C. parinaud's syndrome Parinaud syndrome is defined as a constellation -- of upward gaze palsy, convergence retraction nystagmus, light-near dissociation, and bilateral lid retraction. It is caused by a lesion of the superior colliculus. Option: D. Weber syndrome - Weber syndrome, classically described as a midbrain stroke syndrome and superior alternating hemiplegia, involves oculomotor fascicles in the interpeduncular cisterns and cerebral peduncle, thereby causing ipsilateral third nerve palsy with contralateral hemiparesis.</p>\n<p><strong>Extraedge:</strong></p><p>Millard–Gubler syndrome is a lesion of the pons. It is also called ventral pontine syndrome .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Following is a list of symptoms. Choose the correct symptoms that are present in lateral medullary syndrome/Wallenberg syndrome. Ipsilateral ataxia Ipsilateral bulbar paralysis Loss of gag reflex Ipsilateral Horner syndrome Ipsilateral loss of pain and temperature on the face Contralateral loss of pain and temperature of the body. Nystagmus Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1 2 4 5 7", "correct": false}, {"label": "B", "text": "2 3 4 5", "correct": false}, {"label": "C", "text": "1 2 3 4 5 6", "correct": false}, {"label": "D", "text": "1 2 3 4 5 6 7", "correct": true}], "correct_answer": "D. 1 2 3 4 5 6 7", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1 2 3 4 5 6 7 Features of the lateral medullary syndrome Features of lateral medullary syndrome Dysfunction Effects Vestibular nuclei Vestibular system: Vomiting, vertigo, nystagmus Inferior cerebellar peduncle Ipsilateral cerebellar signs including ataxia, dysmetria (past pointing), dysdiadochokinesia Central tegmental tract Palatal myoclonus Lateral spinothalamic tract Contralateral deficits in pain and temperature sensation from body (limbs and torso) Spinal trigeminal nucleus & tract Ipsilateral deficits in pain and temperature sensation from face Nucleus ambiguus (which affects vagus nerve and glossopharyngeal nerve) - localizing lesion (all other deficits are present in lateral pontine syndrome as well) Ipsilateral laryngeal, pharyngeal, and palatal hemiparalysis: dysphagia, hoarseness, absent gag reflex (efferent limb-CNX) Descending sympathetic fibers Ipsilateral Horner's syndrome (ptosis, miosis, & anhidrosis)</p>\n<p><strong>Highyeild:</strong></p><p>The lateral medullary syndrome is a neurological disorder causing a range of symptoms due to ischemia in the lateral part of the medulla oblongata in the brainstem. The ischemia is a result of a blockage most commonly in the vertebral artery or the posterior inferior cerebellar artery. The lateral medullary syndrome is also called Wallenberg's syndrome, posterior inferior cerebellar artery (PICA) syndrome and vertebral artery syndrome.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A . 1 2 4 5 7 Option: B . 2 3 4 5 Option: C. 1 2 3 4 5 6 All seven statements are correct symptoms of the lateral medullary syndrome, therefore options A, B and C are incorrect answers and the correct answer is option D.</p>\n<p><strong>Extraedge:</strong></p><p>The lateral medullary syndrome is the clinical manifestation resulting from occlusion of the posterior inferior cerebellar artery (PICA) or one of its branches or of the vertebral artery, in which the lateral part of the medulla oblongata infarcts, resulting in a typical pattern. The most commonly affected artery is PICA, specifically the lateral medullary segment.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A professor while taking a lecture on various brainstem syndromes showed a radiograph of Digital subtraction angiography of a patient suffering from Wallenberg syndrome and told the students that the infraction or vessel marked with A is responsible for the development of the above pathology. Identify vessel A in the given image.", "options": [{"label": "A", "text": "Posterior Cerebral Artery", "correct": false}, {"label": "B", "text": "Anterior inferior cerebellar artery", "correct": false}, {"label": "C", "text": "Posterior inferior cerebellar artery", "correct": true}, {"label": "D", "text": "Superior cerebellar artery", "correct": false}], "correct_answer": "C. Posterior inferior cerebellar artery", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759707867-QTDA056008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior inferior cerebellar artery PICA is the main vessel affected in the case of Wallenberg syndrome. Digital Subtraction Angiography of the Vertebrobasilar Circulation</p>\n<p><strong>Highyeild:</strong></p><p>The following clinical findings are noted in Wallenberg syndrome, on the side of the lesion: Vertigo with nystagmus (inferior vestibular nucleus and pathways). The nystagmus is typically central, beating to the direction of gaze. Nausea and vomiting, and sometimes hiccups, are associated with vertigo. Hiccups can often be intractable Dysphonia, dysarthria, and dysphagia (different nuclei and fibers of the IX and X nerves), often present with ipsilateral loss of the gag reflex Horner syndrome; miosis, ptosis, and anhidrosis (sympathetic fibers) Ipsilateral ataxia with a tendency to fall to the ipsilateral side (inferior cerebellar hemisphere, spinocerebellar fibers, and inferior cerebellar peduncle) Pain and numbness with impaired facial sensation on the face (descending trigeminal tract) Impaired taste sensation (involvement of nucleus Tractus solitarius) On the contralateral side: Impaired pain and temperature sensation in the arms and legs (spinothalamic tract) It is important to note that there is no or only minimal weakness of the contralateral side (corticospinal fibers are ventral in location)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- PCA, AICA and SCA are not involved in Wallenberg syndrome</p>\n<p><strong>Extraedge:</strong></p><p>Medial medullary syndrome is a form of stroke that affects the medial medulla of the brain. It is usually caused by atherothrombotic occlusion of paramedian branches of the anterior spinal artery, the vertebral artery, or the basilar artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient presented with acoustic neuroma applying pressure over a cerebellopontine angle. Which of the following symptoms will be least likely to present?", "options": [{"label": "A", "text": "Ipsilateral Facial Paralysis", "correct": false}, {"label": "B", "text": "Tinnitus", "correct": false}, {"label": "C", "text": "Contralateral ataxia", "correct": true}, {"label": "D", "text": "Loss of the ipsilateral (same side of the body) corneal reflex", "correct": false}], "correct_answer": "C. Contralateral ataxia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Contralateral ataxia Contralateral ataxia is not seen in cerebellopontine angle syndrome, but Ipsilateral ataxia is seen.</p>\n<p><strong>Highyeild:</strong></p><p>Cerebellopontine angle syndrome Cerebellopontine angle (Fig. 25.10): The anatomical structures located in the cerebellopontine angle include choroid plexuses of IV ventricle, flocculus, VII and VIII cranial nerves. A tumour, acoustic neuroma, in this angle arises usually in relation to VIII nerve. Features are: Ipsilateral facial paralysis and loss of taste in anterior two-thirds of tongue due to damage to fibres of facial nerve. Deafness and vertigo due to damage to both the parts of VIII nerve. Ataxia on the affected side due to involvement of the flocculus. Absence of corneal reflex on the side of lesion due to damage to nucleus of V nerve including its spinal tract. Write the above Features in Tabular form</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Ipsilateral Facial Paralysis Option:B. Tinnitus Option:D. Loss of the ipsilateral (same side of the body) corneal reflex Option: A, B and D. Features present in cerebellopontine angle syndrome.</p>\n<p><strong>Extraedge:</strong></p><p>The cerebellopontine angle syndrome is a distinct neurological syndrome of deficits that can arise due to the closeness of the cerebellopontine angle to specific cranial nerves. Indications include unilateral hearing loss (85%), speech impediments, disequilibrium, tremors or other loss of motor control. The cerebellopontine angle cistern is a subarachnoid cistern formed by the cerebellopontine angle that lies between the cerebellum and the pons. It is filled with cerebrospinal fluid and is a common site for the growth of acoustic neuromas or schwannomas.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 70-year-old male patient presented to the emergency casualty, with weakness in bilateral lower limbs. On examination, the patient is unresponsive with GCS 12, temp –103.7 F, 122 pulses, and pinpoint pupils. NCCT head suggests there is a haemorrhage present involving a particular area of the brainstem. Which of the following parts of the brainstem is likely affected?", "options": [{"label": "A", "text": "Midbrain", "correct": false}, {"label": "B", "text": "Pons", "correct": true}, {"label": "C", "text": "Medulla", "correct": false}, {"label": "D", "text": "Cerebellum", "correct": false}], "correct_answer": "B. Pons", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pons The given clinical scenario is suggestive of pontine haemorrhage. Pontine haemorrhage: This entity has the following features: Bilateral paralysis of face and limbs due to involvement of VII nerve nucleus and all corticospinal fibres. Deep coma due to damage to the reticular formation. Hyperpyrexia due to cutting off of the temperature-regulating fibres from the hypothalamus. Pin point pupil due to damage to sympathetic ocular fibres. Pontine haemorrhage is usually</p>\n<p><strong>Highyeild:</strong></p><p>Clinical presentation of Pontine Hemorrhage Patients present with sudden and precipitous neurological deficits. Depending on the speed at which the haematoma enlarges and the exact location, the presentation may include: decreased level of consciousness (most common) long tract signs including tetraparesis cranial nerve palsies seizures Cheyne-Stokes respiration</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options: A, C & D doesn't show the symptoms mentioned above when gets affected</p>\n<p><strong>Extraedge:</strong></p><p>' Pontine haemorrhages are a common form of intracerebral haemorrhage, and usually are a result of poorly controlled long-standing hypertension, although also have other causes. When due to chronic hypertension, the stigmata of chronic hypertensive encephalopathy are often present.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following pathology occurs when there is thrombosis of the artery marked with P.", "options": [{"label": "A", "text": "Wallenberg Syndrome", "correct": false}, {"label": "B", "text": "Millard gubler syndrome", "correct": true}, {"label": "C", "text": "Parinaud’s syndrome", "correct": false}, {"label": "D", "text": "Weber syndrome", "correct": false}], "correct_answer": "B. Millard gubler syndrome", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759707941-QTDA056011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Millard gubler syndrome Millard- Gubler syndrome (MGS) , also known as facial abducens hemiplegia syndrome or ventral pontine syndrome, is one of the classical crossed brainstem syndromes characterized by a unilateral lesion of the basal portion of the caudal pons involving abducens (VI) and the facial (VII) cranial nerves and the pyramidal tract fibers. The diagnosis of Millard-Gubler syndrome is confirmed by clinical examination of cranial nerves VI and VII along with hemiplegia of the upper and lower extremities. It is caused by blockage or compromise of pontine branches of the basilar artery marked as point P in the given image.</p>\n<p><strong>Highyeild:</strong></p><p>Millard-Gubler syndrome , also known as a ventral pontine syndrome , is one of the crossed paralysis syndromes, which are characterized by cranial nerves VI and VII palsies with contralateral body motor or sensory disturbances. Clinical presentation ipsilateral facial and contralateral body hemiplegia due to pyramidal tract involvement. isotropism and diplopia that is worsened while the patient looks toward the lesion. ipsilateral facial paresis and loss of corneal reflex.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. PICA is the main vessel affected by Wallenberg syndrome. Option: C. Parinaud’s syndrome Parinaud syndrome is defined as a constellation of upward gaze palsy, convergence retraction nystagmus, light-near dissociation, and bilateral lid retraction. It is caused by a lesion of the superior colliculus. Option: D. Weber syndrome - Weber syndrome, classically described as a midbrain stroke syndrome and superior alternating hemiplegia, involves oculomotor fascicles in the interpeduncular cisterns and cerebral peduncle, thereby causing ipsilateral third nerve palsy with contralateral hemiparesis.</p>\n<p><strong>Extraedge:</strong></p><p>Millard- Gubler syndrome (MGS) is one of the classical crossed brainstem syndromes characterized by a unilateral lesion of the basal portion of the caudal pons involving fascicles of abducens (VI) and the facial (VII) cranial nerve, and the pyramidal tract fibers.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Match the following brainstem syndrome with their most common respectively involved vessels. Select the correct answer from the given below code:", "options": [{"label": "A", "text": "a 1, b 2, c 3, d 4", "correct": false}, {"label": "B", "text": "a 4, b 2, c 1, d 2", "correct": true}, {"label": "C", "text": "a 4, b 3, c 2, d 1", "correct": false}, {"label": "D", "text": "a 1, b 4, c 2, d 4", "correct": false}], "correct_answer": "B. a 4, b 2, c 1, d 2", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759708043-QTDA056012IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>a 4, b 2, c 1, d 2 The following are the vessels associated with the given brainstem syndrome: Weber syndrome – post. Cerebral artery Millard Gubler syndrome – basilar artery Medial medullary syndrome – vertebral artery > anterior spinal artery Lateral medullary syndrome – vertebral artery >PICA</p>\n<p><strong>Highyeild:</strong></p><p>Wallenberg syndrome Anatomical location Presenting symptoms Spinothalamic tract Contralateral loss of pain and temperature sensation Spinal trigeminal nucleus Ipsilateral facial loss of pain and temperature Nucleus ambiguus Supplies vagus and glossopharyngeal nerves; dysphagia/dysphonia/ diminished gag reflex Inferior vestibular nucleus Vertigo/diplopia/nystagmus/ vomiting Sympathetic fibres Ipsilateral Horners syndrome Central trigeminal tract Palatal clonus Inferior cerebellar peduncle Ataxia</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. a 1, b 2, c 3, d 4 Option:C. a 4, b 3, c 2, d 1 Option:D. a 1, b 4, c 2, d 4 The following are the vessels associated with the given brainstem syndrome: Weber syndrome – post. Cerebral artery Millard Gubler syndrome – basilar artery Medial medullary syndrome – vertebral artery > anterior spinal artery Lateral medullary syndrome – vertebral artery >PICA Therefore all Options A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The posterior inferior cerebellar artery (PICA) usually originates from the vertebral artery (VA) at an average distance of approximately 16 or 17 mm below the vertebrobasilar junction.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following arteries compromise will result in the development of medial medullary syndrome?", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "b", "correct": false}, {"label": "C", "text": "c", "correct": true}, {"label": "D", "text": "d", "correct": false}], "correct_answer": "C. c", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759708071-QTDA056013IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C The vertebral artery is affected in medial medullary syndrome. Circle of Willis</p>\n<p><strong>Highyeild:</strong></p><p>Medial medullary syndrome, also known as Déjerine syndrome, is secondary to thrombotic or embolic occlusion of small perforating branches from vertebral or proximal basilar arteries supplying the medial aspect of the medulla oblongata.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Posterior inferior cerebellar artery is involved in the lateral medullary syndrome. Option: B. Basilar artery is involved in Millard Gubler Option: D. Posterior cerebral artery is involved in Weber syndrome.</p>\n<p><strong>Extraedge:</strong></p><p>The medial medullary syndrome is characterized by contralateral hemiplegia/hemiparesis as well as a chemosensory loss with ipsilateral hypoglossal palsy (ipsilateral tongue weakness and atrophy) from the involvement of CN XII nucleus. Other manifestations such as vertigo, nausea, or contralateral limb ataxia are also reported.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Your professor is taking a lecture on brainstem medullary syndromes. He asks you to demonstrate a finding that you may see in medial medullary syndrome and not in lateral medullary syndrome. Which of the following will be your answer?", "options": [{"label": "A", "text": "Horner Syndrome", "correct": false}, {"label": "B", "text": "Tongue deviation towards the opposite side.", "correct": true}, {"label": "C", "text": "Vertigo", "correct": false}, {"label": "D", "text": "Contralateral loss of pain and temperature.", "correct": false}], "correct_answer": "B. Tongue deviation towards the opposite side.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tongue deviation towards the opposite side. XII cranial nerve is involved in medial medullary syndrome and is spared in lateral medullary syndrome.</p>\n<p><strong>Highyeild:</strong></p><p>Features of the lateral medullary syndrome Features of lateral medullary syndrome Dysfunction Effects Vestibular nuclei Vestibular system: Vomiting, vertigo, nystagmus Inferior cerebellar peduncle Ipsilateral cerebellar signs including ataxia, dysmetria (past pointing), dysdiadochokinesia Central tegmental tract Palatal myoclonus Lateral spinothalamic tract Contralateral deficits in pain and temperature sensation from body (limbs and torso) Spinal trigeminal nucleus & tract Ipsilateral deficits in pain and temperature sensation from face Nucleus ambiguus (which affects vagus nerve and glossopharyngeal nerve) - localizing lesion (all other deficits are present in lateral pontine syndrome as well) Ipsilateral laryngeal, pharyngeal, and palatal hemiparalysis: dysphagia, hoarseness, absent gag reflex (efferent limb-CNX) Descending sympathetic fibers Ipsilateral Horner's syndrome (ptosis, miosis, & anhidrosis)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Horner syndrome is seen in lateral medullary syndrome due to damage to the sympathetic chain in lateral medullary syndrome. Option: C . Vertigo is seen due to damage to the vestibular nucleus. Option: D . Loss of pain and temperature is seen due to damage to the spinothalamic tract.</p>\n<p><strong>Extraedge:</strong></p><p>Medial medullary syndrome The medial medullary syndrome is characterized by contralateral hemiplegia/hemiparesis as well as a chemosensory loss with ipsilateral hypoglossal palsy (ipsilateral tongue weakness and atrophy) from the involvement of CN XII nucleus. Other manifestations such as vertigo, nausea, or contralateral limb ataxia are also reported.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Thrombosis in the marked vessel will result in which of the following brainstem syndrome?", "options": [{"label": "A", "text": "Millard Gubler Syndrome", "correct": false}, {"label": "B", "text": "Weber syndrome", "correct": true}, {"label": "C", "text": "Wallenberg syndrome", "correct": false}, {"label": "D", "text": "Medial medullary syndrome", "correct": false}], "correct_answer": "B. Weber syndrome", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759708158-QTDA056015IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Weber syndrome Weber syndrome is caused by a compromise of blood flow in the posterior cerebral artery.</p>\n<p><strong>Highyeild:</strong></p><p>Weber syndrome, classically described as a midbrain stroke syndrome and superior alternating hemiplegia, involves oculomotor fascicles in the interpeduncular cisterns and cerebral peduncle, thereby causing ipsilateral third nerve palsy with contralateral hemiparesis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Millard Gubler syndrome- Pontine branches of the basilar artery Option: D. Medial medullary syndrome – vertebral artery > anterior spinal artery Option: C. lateral medullary syndrome – vertebral artery >PICA</p>\n<p><strong>Extraedge:</strong></p><p>Medial medullary syndrome , also known as Déjerine syndrome, is secondary to thrombotic or embolic occlusion of small perforating branches from vertebral or proximal basilar arteries supplying the medial aspect of the medulla oblongata.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 25 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Left subclavian artery forms from:", "options": [{"label": "A", "text": "Left 7th cervical intersegmental artery", "correct": true}, {"label": "B", "text": "Proximal part of 3rd arch artery", "correct": false}, {"label": "C", "text": "Proximal part of 6th arch artery", "correct": false}, {"label": "D", "text": "Distal part of 6th arch artery", "correct": false}], "correct_answer": "A. Left 7th cervical intersegmental artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left 7th cervical intersegmental artery The left subclavian artery is derived entirely from the left seventh intersegmental artery . In contrast, the right portions are derived from the right fourth arch and the right dorsal aorta. The left 7th intersegmental artery forms the left subclavian artery .</p>\n<p><strong>Highyeild:</strong></p><p>Right subclavian artery arises from the right fourth aortic arch proximally and the right seventh intersegmental artery distally.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Proximal part of 3rd arch artery The proximal part of 3rd arch artery gives rise to the common carotid artery Option C. Proximal part of 6th arch artery The proximal part of the 6th arch artery forms the pulmonary artery Option D. Distal part of 6th arch artery The proximal part of the sixth right arch persists as the proximal part of the right pulmonary artery while the distal section degenerates; The sixth left arch gives off the left pulmonary artery and forms the ductus arteriosus. The left dorsal arch forms the ductus arteriosus, which later closes and is termed the ligamentum arteriosum.</p>\n<p><strong>Extraedge:</strong></p><p>The third aortic arch constitutes the commencement of the internal carotid artery and is therefore named the carotid arch. It contributes to the common carotid arteries bilaterally and the proximal portion of the internal carotid arteries bilaterally.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Right subclavian artery forms all of the following structures except:", "options": [{"label": "A", "text": "Right dorsal aorta", "correct": false}, {"label": "B", "text": "Right 4th arch artery", "correct": false}, {"label": "C", "text": "Right 7th cervical intersegmental artery", "correct": false}, {"label": "D", "text": "Left 7th cervical intersegmental artery", "correct": true}], "correct_answer": "D. Left 7th cervical intersegmental artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left 7th cervical intersegmental artery The left subclavian artery is derived entirely from the left seventh intersegmental artery , whereas the portions of the right are derived from the right fourth arch and the right dorsal aorta. The left 7th cervical intersegmental artery forms the left subclavian artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Right dorsal aorta Option B. Right 4th arch artery Option C. Right 7th cervical intersegmental artery Option A, B, C all are involved in the formation of the right subclavian artery. The right subclavian arises, proximal to distal: right 4th aortic arch right dorsal aorta right 7th intersegmental artery</p>\n<p><strong>Extraedge:</strong></p><p>The greater part of the first arch artery disappears, but its remaining part forms a maxillary artery. The greater part of the second arch artery disappears, but its remaining part forms the hyoid and stapedial arteries in fetal life. The third and fourth arch arteries open into the ventral part of the aortic sac, while the sixth arch artery into the dorsal part of the aortic sac.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The common carotid artery is formed by:", "options": [{"label": "A", "text": "Left 7th cervical intersegmental artery", "correct": false}, {"label": "B", "text": "Proximal part of 3rd arch artery", "correct": true}, {"label": "C", "text": "Proximal part of 6th arch artery", "correct": false}, {"label": "D", "text": "The distal part of the 6th arch artery", "correct": false}], "correct_answer": "B. Proximal part of 3rd arch artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Proximal part of 3rd arch artery The third aortic arch forms the common carotid artery, and the first part of the internal carotid artery Proximal part of the 3rd arch artery gives rise to the common carotid artery.</p>\n<p><strong>Highyeild:</strong></p><p>The third aortic arch forms the common carotid artery and the first part of the internal carotid artery . The remainder of the internal carotid is formed by the cranial portion of the dorsal aorta. The external carotid artery is a sprout of the third aortic arch.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A . Left 7th cervical intersegmental artery The left 7th cervical intersegmental artery forms the Left subclavian artery Whereas the Right 7th cervical intersegmental artery forms the Right common carotid artery. Option C . Proximal part of 6th arch artery Proximal part of 6th arch artery forms pulmonary artery Option D . Distal part of 6th arch artery Distal part of 6th arch artery forms ductus arteriosus.</p>\n<p><strong>Extraedge:</strong></p><p>The fourth aortic arch persists on both sides, but its ultimate fate is different on the right and left sides. On the left, it forms part of the arch of the aorta, between the left common carotid and the left subclavian arteries. On the right, it forms the most proximal segment of the right subclavian artery, the distal part of which is formed by a portion of the right dorsal aorta and the seventh intersegmental artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Pulmonary artery develops from:", "options": [{"label": "A", "text": "Left 7th cervical intersegmental artery", "correct": false}, {"label": "B", "text": "Proximal part of 3rd arch artery", "correct": false}, {"label": "C", "text": "Proximal part of 6th arch artery", "correct": true}, {"label": "D", "text": "Distal part of 6th arch artery", "correct": false}], "correct_answer": "C. Proximal part of 6th arch artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Proximal part of 6th arch artery The proximal part of the 6th arch artery forms a pulmonary artery, whereas Distal part of the 6th arch artery forms the ductus arteriosus.</p>\n<p><strong>Highyeild:</strong></p><p>Derivatives of the Aortic Arches Arch Arterial Derivative 1 Maxillary arteries 2 Hyoid and stapedial arteries 3 Common carotid and first part of the internal carotid arteries 4 left side Arch of the aorta from the left common carotid to the left subclavian arteriesb Right side Right subclavian artery [proximal portion)c Left pulmonary 6 left side artery and ductus arteriosus Right side Right pulmonary artery The remainder of the internal carotid arteries are derived from the dorsal aorta; the external carotid arteries sprout from the third aortic arch. The proximal portion of the aortic arch is derived from the left horn of the aortic sac; the right horn of this sac forms the brachiocephalic artery. The distal portion of the right subclavian artery as well as the left subclavian artery form from the seventh intersegmental arteries on their respective sides.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Left 7th cervical intersegmental artery The left 7th cervical intersegmental artery forms the left subclavian artery. Option B. proximal part of 3rd arch artery Proximal part of the 3rd arch artery gives rise to the common carotid artery. Option D. distal part of 6th arch artery The distal part of 6th arch artery forms ductus arteriosus</p>\n<p><strong>Extraedge:</strong></p><p>The fifth aortic arch either never forms or forms incompletely and then regresses.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Ductus arteriosus develops from:", "options": [{"label": "A", "text": "Left 7th cervical intersegmental artery", "correct": false}, {"label": "B", "text": "Proximal part of 3rd arch artery", "correct": false}, {"label": "C", "text": "Proximal part of 6th arch artery", "correct": false}, {"label": "D", "text": "Distal part of 6th arch artery", "correct": true}], "correct_answer": "D. Distal part of 6th arch artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Distal part of 6th arch artery The sixth aortic arch , also known as the pulmonary arch, gives off an important branch that grows toward the developing lung bud. On the right side, the proximal part becomes the proximal segment of the right pulmonary artery . The distal portion of this arch loses its connection with the dorsal aorta and disappears. On the left, the distal part persists during intrauterine life as the ductus arteriosus.</p>\n<p><strong>Highyeild:</strong></p><p>The nerve of the sixth arch (recurrent laryngeal) is at first caudal to the artery of this arch. With the disappearance of part of the sixth arch artery on the right side, the nerve moves cranially and comes into a relationship with the right fourth arch artery (subclavian). On the left side, it retains its relationship to that part of the sixth arch which forms the ductus arteriosus. With the elongation of the neck, and the descent of the heart, these nerves are dragged downward and, therefore, have to follow a recurrent course back to the larynx. Images A and B show the relationship of the vagus and recurrent laryngeal nerves to the aortic arches.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Left 7th cervical intersegmental artery The left 7th intersegmental artery forms the left subclavian artery. Option B. proximal part of 3rd arch artery The proximal part of the 3rd arch artery gives rise to the common carotid artery. Option C. proximal part of 6th arch artery The sixth aortic arch , also known as the pulmonary arch, gives off an important branch that grows toward the developing lung bud. On the right side, the proximal part becomes the proximal segment of the right pulmonary artery . The distal portion of this arch loses its connection with the dorsal aorta and disappears.</p>\n<p><strong>Extraedge:</strong></p><p>Sixth aortic arch - The right and left arches separate into ventral and dorsal segments. The ventral segments are responsible for the formation of the pulmonary arteries bilaterally. The left ventral arch also contributes to the formation of the pulmonary trunk . The right dorsal arch regresses.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A newborn infant suffers from cyanotic heart disease caused by the great arteries (TGA) transposition. In a given situation, the aorta arises from which of the structures?", "options": [{"label": "A", "text": "Ductus Arteriosus", "correct": false}, {"label": "B", "text": "Left atrium", "correct": false}, {"label": "C", "text": "Left ventricle", "correct": false}, {"label": "D", "text": "Right ventricle", "correct": true}], "correct_answer": "D. Right ventricle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right ventricle In the Transposition of the great arteries ( TGA), the aorta arises from the right ventricle and the pulmonary trunk arises from the left ventricle. This happens because of the absence of spiralling of the spiral septum . This is the reverse of the normal situation and gives rise to the cyanotic condition in the newborn. The large arteries arise from the truncus arteriosus in the developing heart and thus could not develop from the atria, which are formed from the sinus venosus. The truncus arteriosus and the sinus venosus are at opposite ends of the heart.</p>\n<p><strong>Highyeild:</strong></p><p>Transposition of the great vessels occurs when the conotruncal septum fails to follow its normal spiral course and runs straight down. As a consequence, the aorta originates from the right ventricle, and the pulmonary artery originates from the left ventricle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options B and C are incorrect options because, In Transposition of the great arteries ( TGA), the aorta arises from the right ventricle, and the pulmonary trunk arises from the left ventricle. This happens because of the absence of spiralling of the spiral septum . Option A. Ductus Arteriosus: Thedu ctus arteriosus is the vessel that shunts oxygenated blood from the pulmonary trunk to the arch of the aorta in the fetus. It does not give rise to the aorta.</p>\n<p><strong>Extraedge:</strong></p><p>Transposition of the great vessels, which occurs in 4.8/10,000 births, sometimes is associated with a defect in the membranous part of the interventricular septum . It is usually accompanied by an open ductus arteriosus. Because the secondary heart field (SHF) and neural crest cells contribute to the formation and septation of the outflow tract, respectively, insults to these cells contribute to cardiac defects involving the outflow tract.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Fibrous pericardium develops from:", "options": [{"label": "A", "text": "Septum transversum", "correct": true}, {"label": "B", "text": "Somatopleuric lateral plate mesoderm", "correct": false}, {"label": "C", "text": "Splanchnopleuric lateral plate mesoder", "correct": false}, {"label": "D", "text": "Cardiac jelly", "correct": false}], "correct_answer": "A. Septum transversum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Septum transversum Fibrous pericardium develops from septum transversum. Septum transversum also forms a part of the diaphragm.</p>\n<p><strong>Highyeild:</strong></p><p>The cranial part of the septum transversum gives rise to the central tendon of the diaphragm. It is the origin of the myoblasts that invade the pleuroperitoneal folds resulting in the formation of the muscular diaphragm. The caudal part of the septum transversum is invaded by the hepatic diverticulum, which divides within it to form the liver and thus gives rise to the ventral mesentery of the foregut , which in turn is the precursor of the lesser omentum, the visceral peritoneum of the liver and the falciform ligament .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. somatopleuric lateral plate mesoderm Somatopleuric lateral plate mesoderm forms a parietal layer of the serous pericardium. Option C. splanchnopleuric lateral plate mesoderm Splanchnopleuric lateral plate mesoderm forms cardiac jelly and myoepithelial mantle. Option D. Cardiac jelly Cardiac jelly forms an endocardial cushion, whereas myoepithelial mantle forms cardiac muscles and epicardium (visceral layer of the serous pericardium) cardiac jelly forms endocardial cushion .</p>\n<p><strong>Extraedge:</strong></p><p>After successful craniocaudal folding, the septum transversum picks up innervation from the adjacent ventral rami of spinal nerves C3, C4 and C5 , thus forming the precursor of the phrenic nerve. During the descent of the septum, the phrenic nerve is carried along and assumes its descending pathway.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The parietal layer of the serous pericardium arises from which of the following structures?", "options": [{"label": "A", "text": "Septum Transversum", "correct": false}, {"label": "B", "text": "Somatopleuric lateral plate mesoderm", "correct": true}, {"label": "C", "text": "Splanchnopleuric lateral plate mesoderm", "correct": false}, {"label": "D", "text": "Cardiac jelly", "correct": false}], "correct_answer": "B. Somatopleuric lateral plate mesoderm", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Somatopleuric lateral plate mesoderm The parietal layer of the serous pericardium arises from the Somatopleuric lateral plate mesoderm.</p>\n<p><strong>Highyeild:</strong></p><p>The lateral plate mesoderm will split into two layers, the somatopleuric mesenchyme and the splanchnopleuric mesenchyme . The somatopleuric layer forms the future body wall. The splanchnopleuric layer forms the circulatory system. Spaces within the lateral plate are enclosed and form the intraembryonic coelom. It is formed by the secretion of BMP-4 by the ectoderm.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Septum Transversum Fibrous pericardium develops from the septum transversum. Option C. Splanchnopleuric lateral plate mesoderm The endothelial heart tube is derived from the splanchnopleuric mesoderm related to the pericardial cavity. The tube invaginates into the pericardial sac on its dorsal side. As it does so, the splanchnopleuric mesoderm lining the dorsal side of the pericardial cavity proliferates to form a thick layer called the myoepicardial mantle (or epimyocardial mantle). Option D. Cardiac jelly Cardiac jelly forms an endocardial cushion, whereas myoepithelial mantle forms cardiac muscles and epicardium (visceral layer of the serous pericardium) cardiac jelly forms endocardial cushion.</p>\n<p><strong>Extraedge:</strong></p><p>Cardiac progenitor cells appear at the caudal epiblast, lateral to primitive streak during the 16th–18th days of development. They migrate cranially in an orderly sequence through the primitive streak into the splanchnopleuric layer of intraembryonic mesoderm, where they form a horseshoe-shaped primary heart field along the cranial end of embryonic disc rostral to buccopharyngeal membrane and neural folds.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Endocardial cushion develops from:", "options": [{"label": "A", "text": "Septum Transversum", "correct": false}, {"label": "B", "text": "Somatopleuric lateral plate mesoderm", "correct": false}, {"label": "C", "text": "Splanchnopleuric lateral plate mesoderm", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. Splanchnopleuric lateral plate mesoderm", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Splanchnopleuric lateral plate mesoderm Endocardial cushion, formed from cardiac jelly, is a derivative of splanchnopleuric lateral plate mesoderm.</p>\n<p><strong>Highyeild:</strong></p><p>The endocardial cushions are thought to arise from a subset of endothelial cells that undergo epithelial-mesenchymal transition. These cells break cell-to-cell contacts and migrate into the cardiac jelly (towards the interior of the heart tube). These migrated cells form the \"swellings\" called the endocardial cushions seen in the heart tube.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Septum Transversum Fibrous pericardium develops from the septum transversum. Option B. somatopleuric lateral plate mesoderm The parietal layer of the serous pericardium arises from the somatopleuric lateral plate mesoderm. Option D. None of the above Endocardial cushion, formed from cardiac jelly, is a derivative of splanchnopleuric lateral plate mesoderm. Hence d) none of the above is incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>Upon sectioning of the heart the atrioventricular endocardial cushions can be observed in the lumen of the atrial canal as two thickenings, one on its dorsal and another on its ventral wall. These thickenings will go on to fuse and remodel to eventually form the valves and septa of the mature adult heart.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Myoepicardial mantles form which of the following structures?", "options": [{"label": "A", "text": "Cardiac Muscles", "correct": true}, {"label": "B", "text": "Endocardial cushion", "correct": false}, {"label": "C", "text": "Fibrous pericardium", "correct": false}, {"label": "D", "text": "Serous pericardium", "correct": false}], "correct_answer": "A. Cardiac Muscles", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cardiac Muscles Myoepicardial mantles form cardiac muscles. The Heart tube invaginates into the pericardial sac on its dorsal side. As it does so, the splanchnopleuric mesoderm lining the dorsal side of the pericardial cavity proliferates to form a thick layer called the myoepicardial mantle (or epimyocardial mantle). When the invagination is complete, the myoepicardial mantle completely surrounds the heart tube. It gives rise to the cardiac muscle (myocardium) and also to the visceral layer of pericardium (epicardium). The parietal layer of pericardium is derived from somatopleuric mesoderm.</p>\n<p><strong>Highyeild:</strong></p><p>The heart tubes fuse, and the mesenchyme around them thickens to form the myoepicardial mantle, which at first is separated from the endothelial wall of the tube by the cardiac jelly (gelatinous connective tissue substance). The jelly is later invaded by mesenchymal cells. The inner endocardial tube will become the internal endothelial lining of the heart, the endocardium; the myoepicardial mantle gives rise to the myocardium (heart muscle) and epicardium or visceral pericardium.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. endocardial cushion The endocardial cushion is formed by cardiac jelly. Option C. fibrous pericardium Fibrous pericardium develops from septum transversum. Option D. serous pericardium Serous pericardium- Parietal layer of the serous pericardium arises from somatopleuric lateral plate mesoderm, whereas Visceral layer of serous pericardium arise from the epicardium.</p>\n<p><strong>Extraedge:</strong></p><p>Endocardial cushions, or atrioventricular cushions, refer to a subset of cells in the development of the heart that play a vital role in the proper formation of the heart septa. They develop on the atrioventricular canal and conotruncal region of the bulbus cordis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Smooth part of the right atrium is derived from which of the following structures?", "options": [{"label": "A", "text": "Sinus Venosus", "correct": true}, {"label": "B", "text": "Primitive atrium", "correct": false}, {"label": "C", "text": "Primitive ventricle", "correct": false}, {"label": "D", "text": "Bulbus cordis", "correct": false}], "correct_answer": "A. Sinus Venosus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sinus Venosus The smooth part of the right atrium is derived from the sinus venosus. Absorption of right horn of sinus venosus into the right half of primitive atrium: This forms the smooth part (sinus venarum) behind crista terminalis develops from absorption of the right horn of sinus venosus into the right atrium by great enlargement of the sinoatrial orifice.</p>\n<p><strong>Highyeild:</strong></p><p>The main right atrium is derived from three sources. They are: Right half of the primitive atrium: It forms the rough trabeculated part (atrium proper) in front of crista terminalis including the right auricle. Absorption of right horn of sinus venosus into the right half of primitive atrium: This forms the smooth part (sinus venarum) behind crista terminalis develops from absorption of the right horn of sinus venosus into the right atrium by great enlargement of the sinoatrial orifice. Absorption of the right half of the AV canal: Most ventral smooth part.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. primitive atrium The primitive atrium forms a rough part of both atria. Option C. primitive ventricle The primitive ventricle or embryonic ventricle of the developing heart, together with the bulbus cordis that lies in front of it, gives rise to the left and right ventricles. The primitive ventricle provides the trabeculated parts of the walls, and the bulbus cordis the smooth parts. Option D. bulbus cordis The bulbus cordis is the cranial most part (arterial end) of the developing heart tube. It is divisible into three parts, i.e. (1) proximal, (2) middle and (3) distal. The proximal one-third of the bulbus cordis merges with the cavity of the primitive ventricle and forms the bulboventricular chamber. It takes part in forming the trabeculated part of the right ventricle. The middle part (conus cordis) forms the outflow part of both the ventricles. The distal part (truncus arteriosus) undergoes division by spiral aortopulmonary septum into ascending aorta and plumonary trunk. The spiral septum is formed by a union of right superior and left inferior truncus swellings or cushions.</p>\n<p><strong>Extraedge:</strong></p><p>In the embryo, the thin walls of the sinus venosus are connected below with the right ventricle, and medially with the left atrium, but are free in the rest of their extent. It receives blood from the vitelline vein, umbilical vein and common cardinal vein. The sinus venosus originally starts as a paired structure but shifts towards associating only with the right atrium as the embryonic heart develops. The left portion shrinks in size and eventually forms the coronary sinus (right atrium) and oblique vein of the left atrium, whereas the right part becomes incorporated into the right atrium to form the sinus venarum. Division of Primitive Heart tube</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Genes involved in cardiac development include :", "options": [{"label": "A", "text": "Nkx-2.5", "correct": false}, {"label": "B", "text": "TBX-5", "correct": false}, {"label": "C", "text": "HAND-1", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above Option A. Nkx-2 NKX -2 (Nirenberg and Kim-2) gene is a master gene regulating heart development. Option B. TBX-5 TBX-5 gene is responsible for septations. Option C. HAND-1 HAND-1 is involved in the formation of ventricles Some Cardiac muscles also develop from neural crest cells.</p>\n<p><strong>Highyeild:</strong></p><p>NKX2.5 contains a homeodomain and is a homologue of the gene tinman that regulates heart development in Drosophila. TBX5 is another transcription factor that contains a DNA-binding motif known as the T-box. Expressed later than NKX2.5, it plays an important role in septation. HAND 1 and HAND 2, under the regulation of NKX2.5, also contribute to expan- sion and differentiation of the ventricles.</p>\n<p><strong>Extraedge:</strong></p><p>Cardiac looping is dependent upon several factors, including the laterality pathway and expression of the transcription factor PITX2 in lateral plate mesoderm on the left side. PITX2 may play a role in the deposition and function of ex- tracellular matrix molecules that assist in looping.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about the Pentalogy of Cantrell.", "options": [{"label": "A", "text": "Congenital abnormality consisting of the absence of the diaphragmatic portion of the pericardium", "correct": false}, {"label": "B", "text": "Midline closure defects, including sternal and abdominal wall defects;", "correct": false}, {"label": "C", "text": "Anterior diaphragmatic defect; and congenital heart defects", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above Abdominal wall defects in the pentalogy of Cantrell occur above the umbilicus (supraumbilical) and in the midline and have a wide range of presentations. Diastasis recti, hernias, and omphalocele have all been described in conjunction with the pentalogy. Sternal defects, too, have a range of presentations, from an absence of the xiphoid process to shortened or cleft sternum. If the sternal defect is large enough, the neonate may have ectopia cordis, in which the heart is located outside the thorax.</p>\n<p><strong>Highyeild:</strong></p><p>Abdominal wall defects in the pentalogy of Cantrell occur above the umbilicus (supraumbilical) and in the midline and have a wide range of presentations. Diastasis recti, hernias, and omphalocele have all been described in conjunction with the pentalogy. Sternal defects, too, have a range of presentations, from an absence of the xiphoid process to shortened or cleft sternum. If the sternal defect is large enough, the neonate may have ectopia cordis, in which the heart is located outside the thorax.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. congenital abnormality consisting of absence of the diaphragmatic portion of the pericardium Option B. midline closure defects, including sternal and abdominal wall defects; Option C. anterior diaphragmatic defect; and congenital heart defects. Pentalogy of Cantrell (or thoracoabdominal syndrome ) is a rare congenital syndrome that causes defects involving the diaphragm, abdominal wall, pericardium, heart and lower sternum. There are five characteristic findings in the pentalogy of Cantrell: an abdominal wall defect, lower sternal defect, congenital heart malformations, absence of the diaphragmatic pericardium, and an anterior diaphragmatic defect So, Option D: All of the above is the correct answer.</p>\n<p><strong>Extraedge:</strong></p><p>Many congenital heart malformations have been described in conjunction with the pentalogy of Cantrell. The most common is ventricular septal defect, found in 72% of cases. Others include atrial septal defect, cardiac diverticulum, pulmonic stenosis, double outlet right ventricle, tetralogy of Fallot, dextrocardia, and transposition of the great vessels.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Premature closure of foramen ovale results in:", "options": [{"label": "A", "text": "Underdeveloped right atrium", "correct": false}, {"label": "B", "text": "Right ventricular hypertrophy", "correct": true}, {"label": "C", "text": "Left ventricular hypertrophy", "correct": false}, {"label": "D", "text": "Pulmonary stenosis", "correct": false}], "correct_answer": "B. Right ventricular hypertrophy", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right ventricular hypertrophy Occasionally, the oval foramen closes during prenatal life . This abnormality, premature closure of the oval foramen, leads to massive hypertrophy of the right atrium and ventricle and underdevelopment of the left side of the heart. Due to premature closure of the foramen ovale, most of the blood starts accumulating on the Right side of the heart, causing hypertrophy of the right side and underdevelopment of the left side. Death usually occurs shortly after birth.</p>\n<p><strong>Highyeild:</strong></p><p>The foramen ovale acts like a one-way valve from right to left. Septum primum is the thin and mobile-like flap, while septum secundum (crista dividens) is thick, firm, and immobile. When blood accumulates in the right atrium, it pushes the septum primum towards the left, foramen ovale opens, and blood flows from the right to the left atrium. When the blood flows from the right to the left atrium, the thin flap of septum primum moves away, and there is no obstruction to the blood flow. But after birth, the left atrium receives blood from the lungs, and pressure within it becomes greater than that in the right atrium. As blood pressure in the left atrium increases, it pushes the septum primum to the right. It comes in opposition with the septum secundum, and the foramen ovale is closed (physiological closure); thus, the blood is prevented from flowing from the left atrium to the right atrium.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A . Underdeveloped right atrium Due to premature closure of the foramen ovale, most of the blood starts accumulating in the right side of the heart, causing hypertrophy of the right side leading to massive hypertrophy of the right atrium and right ventricle and underdevelopment of the left side of the heart. Option C . Left ventricular hypertrophy Due to premature closure of foramen ovale, most of the blood starts accumulating in the Right side of the heart, causing hypertrophy of the right side leading to massive hypertrophy of the right atrium and right ventricle and underdevelopment of the left atrium and left ventricle of the heart. While ventricular hypertrophy occurs naturally as a reaction to aerobic exercise and strength training, it is most frequently referred to as a pathological reaction to cardiovascular disease or high blood pressure. Option D . Pulmonary stenosis Fallot’s tetralogy consists of the following: Interventricular septal defect Aorta overriding the free upper edge of the ventricular septum Pulmonary stenosis Hypertrophy of the right ventricle.</p>\n<p><strong>Extraedge:</strong></p><p>Tetralogy of Fallot occurs in 9.6/10,000 births but occurs as a common feature in individuals with Alagille syndrome. In addition to the heart defect, these people have abnormalities in other organs, including the liver, and a characteristic face with a broad prominent forehead, deep-set eyes, and a small pointed chin.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Interventricular septum develops from all except.", "options": [{"label": "A", "text": "Floor of the ventricle", "correct": false}, {"label": "B", "text": "Right and left bul- bar ridges", "correct": false}, {"label": "C", "text": "Right horn of sinus venosus", "correct": true}, {"label": "D", "text": "AV cushions", "correct": false}], "correct_answer": "C. Right horn of sinus venosus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right horn of sinus venosus The sinus venosus exists distinctly only in the embryonic heart where it is found between the two venae cavae; in the adult, the sinus venosus becomes incorporated into the wall of the right atrium to form a smooth part of the right atrium called the sinus venarum which is separated from the rest of the atrium by a ridge called the crista terminalis.</p>\n<p><strong>Highyeild:</strong></p><p>Ventricular septal defects involving the membranous or muscular portion of the septum are the most common congenital cardiac malformation, occurring as an isolated condition in 12/10,000 births. Most [80%] occur in the muscular region of the septum and resolve as the child grows. Membranous VSDs usually represent a more serious defect and are often associated with abnormalities in the partitioning of the conotruncal region.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Floor of the ventricle A median muscular ridge grows upward from the floor of the primitive ventricle (near its apex) and reaches almost up to the AV cushions. It forms the muscular part of the IV septum. Option B. Right and left bulbar ridges From the conical part of the common ventricular chamber the two ridges (i.e., right and left bulbar ridges) develop in the distal part of the bulbus cordis. They grow and approach each other to fuse together to form the bulbar part of the IV septum. Option D. AV cushions The gap between the upper edge of the muscular part of the IV septum and the lower end of the bulbar part of IV septum is filled by proliferation of tissue from the right side of the AV cushions and from the right and left bulbar ridges. Thus, the membranous part of IV septum is derived from three sources: right bulbar ridge, left bulbar ridge, and AV cushions.</p>\n<p><strong>Extraedge:</strong></p><p>Membranous ventricular septal defects are more common than muscular ventricular septal defects, and are the most common congenital cardiac anomaly.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Unequal division of conus cordis resulting from the anterior displacement of conotruncal septum gives rise to", "options": [{"label": "A", "text": "Persistent Truncus Arteriosus", "correct": false}, {"label": "B", "text": "Coarctation of aorta", "correct": false}, {"label": "C", "text": "Tetralogy of Fallot", "correct": true}, {"label": "D", "text": "Transposition of great vessels", "correct": false}], "correct_answer": "C. Tetralogy of Fallot", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tetralogy of Fallot Tetralogy of Fallot, the most frequently occurring abnormality of the conotruncal region, is due to an unequal division of the conus resulting from anterior displacement of the conotruncal septum.</p>\n<p><strong>Highyeild:</strong></p><p>Displacement of the Conotruncal septum produces four cardiovascular alterations: a narrow right ventricular outflow region, pulmonary infundibular stenosis; a large defect of the interventricular septum; an overriding aorta that arises directly above the septal defect; and hypertrophy of the right ventricular wall because of higher pressure on the right side. Tetralogy of Fallot</p>\n<p><strong>Random:</strong></p><p>\" Explanation for incorrect options: - Option A. Persistent Truncus Arteriosus Persistent truncus arteriosus: In this anomaly spiral septum (aorticopulmonary septum) fails to develop. Pulmonary arteries and aorta arise from a common vessel. Option B. Coarctation of aorta The coarctation means narrowing of the aorta. It occurs due to extension of the process of obliteration of ductus arteriosus (DA) into the aorta. The coarctation of aorta is of two types: preductal and postductal. Preductal type of coarctation of aorta: In this type, a narrow segment of arch of aorta is proximal to the entrance of the DA. The DA persists in this type. Postductal type of coarctation of aorta: In this type, a narrow segment of the arch of aorta is distal to the entrance of the DA. The DA usually obliterates this type. Option D. Transposition of great vessel Transposition of the great vessels occurs when the conotruncal septum fails to follow its normal spiral course and runs straight down. Transposition of great vessels: The aorta arises from the right ventricle, and the pulmonary trunk from the left ventricle. \"</p>\n<p><strong>Extraedge:</strong></p><p>If Tetralogy of Fallot is associated with ASD (Atrial septal defect), it is known as Pentalogy of Fallot. Functional closure of the ductus arteriosus (DA) occurs at birth by contraction of smooth muscles of the DA. Anatomical closure occurs by the proliferation of tunica intima of DA 1–3 months after birth. It is mediated by bradykinin—a substance released from lungs during their initial inflation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The structure is derived from the left 4th aortic arch.", "options": [{"label": "A", "text": "Right common carotid artery", "correct": false}, {"label": "B", "text": "Right subclavian artery", "correct": false}, {"label": "C", "text": "Arch of aorta", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. Arch of aorta", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Arch of aorta The fourth right arch forms the most proximal segment of the right subclavian artery , as far as the origin of its internal thoracic branch. The f ourth left arch forms a part of the arch of the aorta, between the origin of the left common carotid and the left subclavian arteries.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Right common carotid artery Right common carotid artery - arises from the right third aortic arch. Option B. Right subclavian artery Right subclavian artery - arises from the right fourth aortic arch proximally, the right seventh intersegmental artery distally. Option D. None of the above The fourth left arch forms a part of the arch of the aorta, between the origin of the left common carotid and the left subclavian arteries, so Option D is not the correct answer.</p>\n<p><strong>Extraedge:</strong></p><p>Left Subclavian Artery - arises entirely from the left seventh intersegmental artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Photograph shown below represents the stage of development of aortic arches. Aberrant subclavian artery results due to.", "options": [{"label": "A", "text": "Persistence of A and obliteration of B", "correct": false}, {"label": "B", "text": "Persistence of A only", "correct": false}, {"label": "C", "text": "Persistence of B and obliteration of A", "correct": true}, {"label": "D", "text": "Persistence of B only", "correct": false}], "correct_answer": "C. Persistence of B and obliteration of A", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682476439-QTDA076012IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Persistence of B and obliteration of A Aberrant subclavian artery occurs due to the disappearance of the Right fourth aortic arch and the proximal portion of the right dorsal aorta. Here ( A) is the proximal portion of the right dorsal aorta and (B) is the distal portion of the right dorsal aorta. In this case, the right subclavian artery is formed by the distal portion of the right dorsal aorta (‘B’) and the right seventh intersegmental artery. That means (‘A’) disappears and the distal portion of the right dorsal aorta (‘B’) persists. So, Option C is the correct answer and Option A,B and D are incorrect answers.</p>\n<p><strong>Highyeild:</strong></p><p>Normally, the right subclavian artery is contributed by (proximal to distal): Right fourth arch artery, right dorsal aorta and right seventh cervical intersegmental artery.</p>\n<p><strong>Extraedge:</strong></p><p>In case of an abnormal subclavian artery a vascular ring is formed around the trachea and esophagus (right subclavian being posterior to the trachea and esophagus, and arch of aorta being anterior to them). Compression of the trachea and esophagus usually does not occur as the ring is too wide. Sometimes such an abnormal right subclavian artery may compress the esophagus, causing difficulty in swallowing. Clinically this condition is termed ‘ dysphagia lusoria . Dysphagia lusoria</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 22 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The marked structure in image below helps in formation of which of the following structure?Mark the arrow on the pink structure in the image", "options": [{"label": "A", "text": "Pulmonary True", "correct": false}, {"label": "B", "text": "Aorta", "correct": false}, {"label": "C", "text": "Myocardium", "correct": false}, {"label": "D", "text": "A & B", "correct": true}], "correct_answer": "D. A & B", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682502159-QTDA077001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A & B The above-given image is a septum. Aorticopulmonary septum is a spiral septum that divides the truncus arteriosus into the aorta (Option B) and pulmonary trunk (Option A) . It develops from two truncal ridges. The truncal ridges develop due to the proliferation of mesenchymal cells derived from neural crest cells that migrate in the walls of the truncus arteriosus near the conus, so Option D is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>The truncal ridges grow and fuse with each other to form the spiral septum close to the conical part of the ventricle; because the pulmonary trunk and aorta are separated from each other by a septum that is spiral, the relationship of the pulmonary trunk and aorta with each other differs in the lower, middle, and upper parts. In the lower part:The spiral septum and bulbar septum are in the same plane and continuous with each other close to the ventricle. The spiral septum here is in the coronal plane. As a result, the pulmonary trunk is in front, and ascending aorta is posterior. In the middle part: The spiral septum is in the sagittal plane so that the pulmonary trunk and ascending aorta are situated side-by-side, with the aorta being on the right side and the pulmonary trunk on the left side. In the upper part: The spiral septum is again in the coronal plane, but the aorta lies anteriorly, and the pulmonary trunk lies posteriorly. Formation of the aorticopulmonary septum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option C. Myocardium The muscular part of the interventricular septum is derived from the myocardium</p>\n<p><strong>Extraedge:</strong></p><p>Transposition of the great vessels occurs when the conotruncal septum fails to follow its normal spiral course and runs straight down. As a consequence, the aorta originates from the right ventricle, and the pulmonary artery originates from the left ventricle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Anterior displacement of spiral septum results in:", "options": [{"label": "A", "text": "Tetralogy of Fallot", "correct": true}, {"label": "B", "text": "Transposition of greater arteries", "correct": false}, {"label": "C", "text": "Persistent truncus arteriosus", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Tetralogy of Fallot", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tetralogy of Fallot Tetralogy of Fallot, the most frequently occurring abnormality of the conotruncal region, is due to an unequal division of the conus resulting from the anterior displacement of the conotruncal septum.</p>\n<p><strong>Highyeild:</strong></p><p>Displacement of the Conotruncal septum produces four cardiovascular alterations: a narrow right ventricular outflow region, pulmonary infundibular stenosis; a large defect of the interventricular septum; an overriding aorta that arises directly above the septal defect; and hypertrophy of the right ventricular wall because of higher pressure on the right side. Tetralogy of Fallot</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. transposition of greater arteries The transposition of greater arteries is due to the absence of spiralling of the septum. Option C . persistent truncus arteriosus Absent spiral septum results in persistent truncus arteriosus. Option D. None of the above Tetralogy of Fallot, the most frequently occurring abnormality of the conotruncal region, is due to an unequal division of the conus resulting from anterior displacement of the conotruncal septum Option D none of the above is not the correct answer.</p>\n<p><strong>Extraedge:</strong></p><p>Tetralogy of Fallot occurs in 9.6/10,000 births but occurs as a common feature in individuals with Alagille syndrome. In addition to the heart defect, these people have abnormalities in other organs, including the liver, and a characteristic face with a broad prominent forehead, deep set eyes, and a small pointed chin. In 90% of cases, there is a mutation in JAG1, the ligand for NOTCH signalling that regulates neural crest cells forming the conotruncal [outflow tract] septum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Absence of spiral septum results in:", "options": [{"label": "A", "text": "Tetralogy of Fallot", "correct": false}, {"label": "B", "text": "Transposition of greater arteries", "correct": false}, {"label": "C", "text": "Persistent truncus arteriosus", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. Persistent truncus arteriosus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Persistent truncus arteriosus The absence of a spiral septum results in persistent truncus arteriosus. Persistent [common] truncus arteriosus results when the conotruncal ridges fail to form such that no division of the outflow tract occurs.</p>\n<p><strong>Highyeild:</strong></p><p>Persistent truncus arteriosus In persistent [common] truncus arteriosus case, which occurs in O.8/10,000 births, the pulmonary artery arises some distance above the origin of the undivided truncus. Because the ridges also form the interventricular septum, the persistent truncus is always accompanied by a defective interventricular sep The undivided truncus thus overrides both ventricles and receives blood from both sides. Persistent truncus arteriosus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A . Tetralogy of Fallot Anterior displacement of the spiral septum results in tetralogy of Fallot Option B . transposition of greater arteries The transposition of greater arteries is due to the absence of spiralling of the septum. If the spiralling of the spiral septum is absent, it can result in the transposition of great arteries in which the Aorta arises from the right ventricle, whereas the Pulmonary trunk arises from the left ventricle. Option D . None of the above The absence of spiral septum results in persistent truncus arteriosus and hence Option D, none of the above is an incorrect answer.</p>\n<p><strong>Extraedge:</strong></p><p>Patent ductus arteriosus (PDA) is a medical condition in which the ductus arteriosus fails to close after birth: this allows a portion of oxygenated blood from the left heart to flow back to the lungs by flowing from the aorta, which has a higher pressure, to the pulmonary artery. Symptoms are uncommon at birth and shortly thereafter, but later in the first year of life, there is often the onset of an increased work of breathing and failure to gain weight at a normal rate. With time, an uncorrected PDA usually leads to pulmonary hypertension followed by right-sided heart failure.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The muscular part of the interventricular septum is derived from:", "options": [{"label": "A", "text": "Myocardium", "correct": true}, {"label": "B", "text": "Endocardial cushion", "correct": false}, {"label": "C", "text": "Neural crest cells", "correct": false}, {"label": "D", "text": "Septum primum", "correct": false}], "correct_answer": "A. Myocardium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Myocardium The muscular part of the interventricular septum is derived from the myocardium. Muscular part develops from the floor of the ventricle: A median muscular ridge grows upward from the floor of the primitive ventricle (near its apex) and reaches almost up to the AV cushions. It forms the muscular part of the IV septum. It is present in the oblique plane, and its upper margin is concave.</p>\n<p><strong>Highyeild:</strong></p><p>The interventricular (IV) septum consists of three parts. From below upward, these are (a) muscular part, (b) bulbar part, and (c) membranous part. Muscular part develops from the floor of the ventricle: A median muscular ridge grows upward from the floor of the primitive ventricle (near its apex) and reaches almost up to the AV cushions. It forms the muscular part of the IV septum. Bulbar part develops from right and left bulbar ridges : From the conical part of the common ventricular chamber, the two ridges (i.e. right and left bulbar ridges) develop in the distal part of the bulbus cordis. They grow and approach each other to fuse together to form the bulbar part of the IV septum. The gap between the upper margin of the muscular septum and the lower margin of the bulbar septum is called IV foramen. Membranous part: The gap between the upper edge of the muscular part of the IV septum and the lower end of the bulbar part of the IV septum is filled by a proliferation of tissue from the right side of the AV cushions, and from the right and left bulbar ridges. Thus, the membranous part of the IV septum is derived from three sources: the right bulbar ridge, left bulbar ridge, and AV cushions. Formation of the membranous part closes the IV foramen. Components of Interventricular Septum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. endocardial cushion The endocardial cushion forms a membranous part of the interventricular septum. Option C . neural crest cells Neural crest cells form the bulbar septum. Option D. septum primum Septum primum forms the floor of the fossa ovalis.</p>\n<p><strong>Extraedge:</strong></p><p>VSDs involving the membranous or muscular portion of the septum are the most common congenital cardiac malformation, occurring as an isolated condition in 12/10,000 births. Most (80%) cases of VSD in the muscular region of the septum resolve as the child grows. Membranous VSDs usually represent a more serious defect and are often associated with abnormalities in the partitioning of the conotruncal region. Depending on the size of the opening, the blood carried by the pulmonary artery maybe 1.2 to 1.7 times as abundant as that carried by the aorta.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Limbus fossa Ovalis is a remnant of :", "options": [{"label": "A", "text": "Septum Primum", "correct": false}, {"label": "B", "text": "Septum secundum", "correct": true}, {"label": "C", "text": "Endocardial cushion", "correct": false}, {"label": "D", "text": "Myocardium", "correct": false}], "correct_answer": "B. Septum secundum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Septum secundum Limbus fossa ovalis is a remnant of septum secundum. The septum primum which is on the left atrial side, forms the floor of the fossa ovalis, whereas the septum secundum derived from an infolding of the roof of the atrium, forms the limbus of the fossa ovalis</p>\n<p><strong>Highyeild:</strong></p><p>The limbus fossa ovalis (annulus ovalis) is the prominent oval margin of the fossa ovalis. It is most distinct above and at the sides of the fossa; below, it is deficient. A small slit-like valvular opening is occasionally found, at the upper margin of the fossa, leading upward beneath the limbus, into the left atrium; it is the remains of the fetal aperture between the two atria. The fossa ovalis is a depressed structure of varying shapes located in the inferior aspect of the right interatrial septum. A remnant of an interatrial opening, the foramen ovale , which has a significant role in fetal circulation, the fossa ovalis forms by the fusion of the septum primum and septum secundum. Limbus Fossa Ovalis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Septum Primum The floor of fossa Ovalis is a remnant of septum primum. Option C . Endocardial cushion Endocardial cushion forms the membranous part of interventricular septum. Option D . Myocardium The myocardium forms the muscular part of the interventricular septum.</p>\n<p><strong>Extraedge:</strong></p><p>Patent foramen ovale If the atrial septum does not close properly, it leads to a patent foramen ovale (PFO). This type of defect generally works like a flap valve, opening during certain conditions of increased pressure in the chest, such as during strain while having a bowel movement, cough, or sneeze. With enough pressure, blood may travel from the right atrium to the left. If there is a clot in the right side of the heart, it can cross the PFO, enter the left atrium, and travel out of the heart and to the brain, causing a stroke. If the clot travels into a coronary artery, it can cause a heart attack.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the arrow (red) marked structure?", "options": [{"label": "A", "text": "Septum Primum", "correct": true}, {"label": "B", "text": "Septum secundum", "correct": false}, {"label": "C", "text": "Floor of fossa Ovalis", "correct": false}, {"label": "D", "text": "Limbus fossa Ovalis", "correct": false}], "correct_answer": "A. Septum Primum", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682502186-QTDA077006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Septum Primum The arrow (red) marked structure is Septum primum. Fossa Ovalis is a communication via which blood flows from right to left atrium during embryonic life.</p>\n<p><strong>Highyeild:</strong></p><p>The interatrial septum is formed by two septa— septum primum and septum secundum. Septum primum starts developing from the roof of the primitive atrial chamber a little to the left of the opening of sinus venosus. It grows downward towards the septum intermedium (AV septum). The gap between the lower edge of septum primum and septum intermedium is called foramen primum . As septum primum fuses with the AV septum (septum intermedium), the upper part of septum primum breaks down. The foramen thus formed is called foramen secundum (ostium secundum). A second crescent-shaped septum now arises from the roof of the primitive atrial chamber immediately to the right of the septum primum. It is called septum secundum . The septum secundum grows downward towards the septum intermedium. It overlaps the foramen secundum. The right and left atria now communicate with each other through an oblique valvular passage between the upper margin of septum primum and lower margin of septum secundum. This passage is called foramen ovale . The interatrial septum is thus formed by two septa: (a) septum primum that forms the lower part of interatrial septum; and (b) septum secundum that forms the upper part of interatrial septum. Development of Interatrial septum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B: septum secundum is marked by yellow arrow Option C: the floor of fossa ovalis formed by septum primum Option D: Limbus fossa ovalis is formed by septum secundum</p>\n<p><strong>Extraedge:</strong></p><p>Functional Mechanism of Foramen Ovale The foramen ovale acts like a one-way valve from right to left. Septum primum is the thin and mobile-like flap, while septum secundum (crista dividens) is thick, firm, and immo- bile. When blood accumulates in the right atrium, it pushes the septum primum towards the left and foramen ovale opens, and blood flows from the right atrium to the left atrium. When the blood flows from the right to the left atrium, the thin flap of septum primum moves away, and there is no obstruction to the blood flow. But after birth, the left atrium receives blood from the lungs and pressure within it becomes greater than that in the right atrium. As the pressure of blood in the left atrium increases, it pushes the septum pri- mum to the right. It comes in opposition with septum secundum and foramen ovale is closed (physiological closure); thus, the blood is prevented from flowing from the left atrium to the right atrium.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 3-year-old boy is referred to a pediatric cardiologist after a nearby general physician examined the patient and heard a murmur consistent with aortic regurgitation. True about such presentation:", "options": [{"label": "A", "text": "The most common defect of the ventricular septum occurs around the expected site of the membranous septum in the right wall of the aortic vestibule, below the zone of apposition between the non-coronary and right coronary leaflets of the aortic valve", "correct": false}, {"label": "B", "text": "Ventricular septum is incompletely closed by its membranous component", "correct": false}, {"label": "C", "text": "It is often associated with the overriding of the crest of the muscular septum by the aortic orifice, together with pulmonary stenosis or atresia and hypertrophy of the right ventricle ( Fallot’s tetralogy)", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above The given condition is a case of Ventricular Septal defect</p>\n<p><strong>Highyeild:</strong></p><p>VSD is an acyanotic congenital heart defect, also known as a left-to-right shunt, so there are no signs of cyanosis in the early stage. However, uncorrected VSD can increase pulmonary resistance leading to the reversal of the shunt and corresponding cyanosis. In the setting of long-standing large left-to-right shunts, the pulmonary vascular endothelium undergoes irreversible changes resulting in persistent PAH. When the pressure in the pulmonary circulation exceeds the pressure in the systemic circulation, the shunt direction reverses and becomes a right-to-left shunt. This is known as Eisenmenger syndrome, and it occurs in 10% to 15% of patients with VSD.</p>\n<p><strong>Random:</strong></p><p>Explanation for all options: - Option A . The most common defect of the ventricular septum occurs around the expected site of the membranous septum in the right wall of the aortic vestibule, below the zone of apposition between the non-coronary and right coronary leaflets of the aortic valve. A ventricular septal defect ( VSD ) is a defect in the ventricular septum, the wall dividing the left and right ventricles of the heart. The extent of the opening may vary from pin size to the complete absence of the ventricular septum, creating one common ventricle. The membranous portion, which is close to the atrioventricular node, is most commonly affected. It is also the type that will most commonly require surgical intervention, comprising over 80% of cases. (Membranous) This VSD is, by far, the most common type, accounting for 80% of all defects. It is located in the membranous septum inferior to the crista supraventricularis. It often involves the muscular septum which it is commonly known as perimembranous. The septal leaflet of the tricuspid valve sometimes forms a “pouch” that reduces the shunt and can result in spontaneous closure. Membranous VSDs usually represent a more serious defect and are often associated with abnormalities in the partitioning of the conotruncal region. Depending on the size of the opening, blood carried by the pulmonary artery may be 1.2 to 1.7 times as abundant as that carried by the aorta. Membranous ventricular septal defects are more common than muscular ventricular septal defects, and are the most common congenital cardiac anomaly. Option B . Ventricular septum is incompletely closed by its membranous component Ventricular septal defect (VSD) is the most common congenital cardiac anomaly in children and is the second most common congenital abnormality in adults, second only to a bicuspid aortic valve. An abnormal communication between the right and left ventricles and shunt formation is the main mechanism of hemodynamic compromise in VSD. While many VSDs close spontaneously, if they do not, large defects can lead to detrimental complications such as pulmonary arterial hypertension (PAH) , ventricular dysfunction, and an increased risk of arrhythmias. Option C. It is often associated with the overriding of the crest of the muscular septum by the aortic orifice, together with pulmonary stenosis or atresia and hypertrophy of the right ventricle ( Fallot’s tetralogy) VSD develops when there is a developmental abnormality or an interruption of the interventricular septum formation during the complex embryologic heart morphogenesis. VSDs are frequently isolated; however, they can occur in association with other congenital heart defects such as atrial septal defects, patent ductus arteriosus, right aortic arch, and pulmonic stenosis. They are also found in cases of aortic coarctation and subaortic stenosis, and they are a frequent component of complex congenital heart disease such as Tetralogy of Fallot and transposition of great arteries Therefore Option D (all of the above ) is the correct answer.</p>\n<p><strong>Extraedge:</strong></p><p>A TBX5 mutation was recently discovered to cause septal defects in patients with Holt-Oram syndrome. Non-inherited risk factors have been implicated in the development of VSDs; these include maternal infection (rubella, influenza, and febrile illness), maternal diabetes mellitus, and phenylketonuria. Exposure to toxins like alcohol, marijuana, cocaine, and certain medications such as metronidazole and ibuprofen are also linked to VSD.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the cause of the following condition.", "options": [{"label": "A", "text": "Anterior displacement of spiral septum", "correct": false}, {"label": "B", "text": "Persistent ductus arteriosus", "correct": false}, {"label": "C", "text": "Failure of the flap valve of the primary atrial septum to fuse with the infolded muscular rims of the fossa.", "correct": true}, {"label": "D", "text": "Ventricular septum is incompletely closed by its membranous component", "correct": false}], "correct_answer": "C. Failure of the flap valve of the primary atrial septum to fuse with the infolded muscular rims of the fossa.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682502196-QTDA077008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Failure of the flap valve of the primary atrial septum to fuse with the infolded muscular rims of the fossa. The given condition is an atrial septal defect and is due to failure of the flap valve of the primary atrial septum to fuse with the infolded muscular rims of the fossa. ASD is a congenital heart abnormality with an incidence of 6.4/10,000 births and with a 2:1 prevalence in female to male infants. One of the most significant defects is the ostium secundum defect, characterized by a large opening between the left and right atria. It may be caused by excessive cell death and resorption of the septum primum or by inadequate development of the septum secundum . Depending on the size of the opening, considerable intracardiac shunting may occur from left to right. Secundum defects are holes in the true atrial septum i.e., ASDs. They are located in the flap valve covering the oval fossa, the “septum primum” . Termed secundum defects, due to the persistence of the embryonic “ostium secundum”, the defects are often larger than the embryonic communication and involve deficiency of the valve itself. It is, therefore, more accurate to term such defects oval fossa defects. They vary in size from small perforations to the complete absence of the valve guarding the oval fossa.</p>\n<p><strong>Highyeild:</strong></p><p>The most serious abnormality in this group is the complete absence of the atrial septum. This condition, known as a common atrium or cor trilocular biventricular , is always associated with serious defects elsewhere in the heart. Occasionally, the oval foramen closes during prenatal life. This abnormality, premature closure of the oval foramen, leads to massive hypertrophy of the right atrium and ventricle and underdevelopment of the left side of the heart. Death usually occurs shortly after birth. Atrial Septal Defect Common Types</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A : Anterior displacement of spiral septum results in tetralogy of fallot If tetralogy of Fallot is associated with ASD, It is known as Pentology of fallot. Option B : persistent ductus arteriosus results in patent ductus arteriosus. Option D : ventricular septum is incompletely closed by its membranous component in case of ventricular septal defect.</p>\n<p><strong>Extraedge:</strong></p><p>A defect in the ostium primum is occasionally classified as an atrial septal defect, but it is more commonly classified as an atrioventricular septal defect. Ostium primum defects are less common than ostium secundum defects.This type of defect is usually associated with Down syndrome.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following are cyanotic heart diseases except", "options": [{"label": "A", "text": "Atrial Septal Defect", "correct": false}, {"label": "B", "text": "Ventricular septal defect", "correct": false}, {"label": "C", "text": "Patent ductus arteriosus", "correct": false}, {"label": "D", "text": "Fallot's tetralogy", "correct": true}], "correct_answer": "D. Fallot's tetralogy", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fallot's tetralogy Fallot’s tetralogy is cyanotic heart disease, whereas Option a) atrial septal defect, Option b) ventricular septal defect and Option C) patent ductus arteriosus are congenital cyanotic heart disease. Tetralogy of Fallot is a combination of four congenital heart defects. The four defects are a ventricular septal defect (VSD), pulmonary stenosis, a misplaced aorta and a thickened right ventricular wall (right ventricular hypertrophy). They usually result in a lack of oxygen-rich blood reaching the body. If tetralogy of fallot is associated with ASD, It is known as Pentology of fallot.</p>\n<p><strong>Highyeild:</strong></p><p>Fallot’s tetralogy At birth, children may be asymptomatic or present with many severe symptoms. Later in infancy, there are typically episodes of bluish colour to the skin due to a lack of sufficient oxygenation, known as cyanosis. When affected babies cry or have a bowel movement, they may undergo a \"tet spell\" where they turn cyanotic, have difficulty breathing, become limp, and occasionally lose consciousness. Other symptoms may include a heart murmur, finger clubbing, and easy tiring upon breastfeeding.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Atrial Septal Defect Cyanosis in a patient with an atrial septal defect (ASD) is uncommon, but It can result in the development of right-to-left (R-L) shunt across an ASD initially shunting left to right (L-R) in view of elevated pulmonary artery (PA) pressures, as in Eisenmenger's syndrome . Option B. ventricular septal defect Small VSDs only lead to the minimal left-to-right shunt without left ventricular (LV) fluid overload or PAH; they are usually asymptomatic or found incidentally on physical exam. A septal aneurysm's systolic click can sometimes be appreciated in membranous defects. Eisenmenger syndrome manifests in cyanosis, desaturation, dyspnea, syncope, secondary erythrocytosis, and clubbing; in such cases, the typical murmur of VSD can be absent, and accentuated pulmonic component of the second heart sound may be heard. Option C. patent ductus arteriosus A small patent ductus arteriosus often doesn't cause problems and might never need treatment. However, a large, untreated patent ductus arteriosus can let oxygen-poor blood move the wrong way. This can weaken the heart muscle, causing heart failure and other complications.</p>\n<p><strong>Extraedge:</strong></p><p>Genetic factors linked to TOF include various gene mutations or deletions. Gene deletions associated with TOF include chromosome 22 deletion as well as DiGeorge syndrome.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are cyanotic heart diseases except", "options": [{"label": "A", "text": "Atrial septal defect", "correct": true}, {"label": "B", "text": "Transposition of greater arteries", "correct": false}, {"label": "C", "text": "Truncus arteriosus", "correct": false}, {"label": "D", "text": "Fallot's tetralogy", "correct": false}], "correct_answer": "A. Atrial septal defect", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Atrial septal defect Atrial septal defect is a cyanotic heart disease. Acyanotic heart disease if associated with eEsenmenger syndrome, can result in cyanosis. Cyanosis in a patient with an atrial septal defect (ASD) is uncommon, but It can result in the development of a right-to-left (R-L) shunt across an ASD initially shunting left to right (L-R) in view of elevated pulmonary artery (PA) pressures, as in Eisenmenger's syndrome.</p>\n<p><strong>Highyeild:</strong></p><p>The most serious abnormality of the ASD group is the complete absence of the atrial septum. This condition, knowa as common atrium or cor triloculare biventriculare, is always associated with serious defects elsewhere in the heart. Occasionally, the oval foramen closes during prenatal life. This abnormality, premature clo- sure of the oval foramen, leads to massive hypertrophy of the right atrium and ventricle and underdevelopment of the left side of the heart. Death usually occurs shortly after birth.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. transposition of greater arteries Option C. truncus arteriosus Option D. fallot's tetralogy</p>\n<p><strong>Extraedge:</strong></p><p>Ebstein anomaly is a condition where the tricuspid valve is displaced toward the apex of the right ventricle, and as a result, there is an expanded right atrium and a small right ventricle. The valve leaflets are abnormally positioned, and the anterior one is usually enlarged.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 20 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Choose the correct option for the following anomaly:", "options": [{"label": "A", "text": "Persistent right anterior cardinal vein", "correct": false}, {"label": "B", "text": "Persistent left anterior cardinal vein", "correct": true}, {"label": "C", "text": "Persistent left supra cardinal vein", "correct": false}, {"label": "D", "text": "Persistent right umbilical vein", "correct": false}], "correct_answer": "B. Persistent left anterior cardinal vein", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682527252-QTDA078001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Persistent left anterior cardinal vein Usually, after the formation of an oblique anastomosis between both anterior cardinal veins, the caudal part of the left anterior cardinal vein disappears. If oblique anastomosis is not formed, the caudal part of the left Anterior cardinal vein will persist, giving rise to double SVC. Left SVC drains in the coronary sinus</p>\n<p><strong>Highyeild:</strong></p><p>A double superior vena cava is characterized by the persistence of the left anterior cardinal vein and failure of the left brachioce phalic vein to form . The persistent left anterior cardinal vein, the left superior vena cava, drains into the right atrium through the coronary sinus. The coronary sinus drains into the right atrium, and its opening forms one of the boundaries of the triangle of Koch.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Persistent right anterior cardinal vein The anterior cardinal veins ( precardinal veins ) contribute to the formation of the internal jugular veins and together with the common cardinal vein form the superior vena cava. The anastomosis between the two anterior cardinal veins develops into the left brachiocephalic vein. The right anterior cardinal (precardinal) vein proximal to the right brachiocephalic vein forms the superior vena cava (SVC) with the common cardinal, and terminal/proximal segment of the posterior cardinal (postcardinal) vein. The more cranial portions of the bilateral anterior cardinal veins persist and form the internal jugular veins. During the course of their development and involution, the anterior cardinal veins form multiple normal permanent structures, as well as potentially some anomalous structures. Option C. Persistent left supra cardinal vein IVC duplication results from a persistent left supra cardinal vein. A double inferior vena cava occurs when the left Sacrocardinal vein fails to lose its connection with the left sub cardinal vein. The left common iliac vein may or may not be present, but the left gonadal vein remains normal. Option D. Persistent right umbilical vein A persistent right umbilical vein (PRUV) is an uncommon vascular anomaly often detected in utero. In a normal situation, the right umbilical vein begins to obliterate in the 4th week of gestation and disappears by the 7th week. With a PRUV, the right umbilical vein remains open, and the left umbilical vein usually obliterates. A PRUV may also be supernumerary.</p>\n<p><strong>Extraedge:</strong></p><p>Absence of the inferior vena cava aris es when the right sub cardinal vein fails to make its connection with the liver and shunts its blood directly into the right supra cardinal vein. Hence, the bloodstream from the caudal part of the bodyreaches the heart by way of the azygos vein and superior vena cava. The hepatic vein enters into the right atrium at the site of the inferior vena cava. Usually, this abnormality is associated with other heart malformations.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A coronary sinus develops from which of the following structure?", "options": [{"label": "A", "text": "Left horn of sinus venosus", "correct": true}, {"label": "B", "text": "Right anterior cardiac vein", "correct": false}, {"label": "C", "text": "Right posterior cardiac vein", "correct": false}, {"label": "D", "text": "Right mesonephric vein", "correct": false}], "correct_answer": "A. Left horn of sinus venosus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left horn of sinus venosus A coronary sinus develops from the left horn of the sinus venosus. The coronary sinus drains into the right atrium, forming major venous drainage for the Heart. When the left common cardinal vein is obliterated at 10 weeks, all that remains of the left sinus horn is the oblique vein of the left atrium and the coronary sinus. The remains of the left sinus horn are the oblique vein of the left atrium and the coronary sinus</p>\n<p><strong>Highyeild:</strong></p><p>The superior portion of the right venous valve disappears entirely. The inferior portion develops into two parts: (1) the valve of the inferior vena cava and (2) the valve of the coronary sinus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B : Right anterior cardiac vein forms right brachiocephalic vein Option C : Right posterior cardiac vein cranial part forms the azygos vein, while the caudal part contributes to the formation of IVC. Option D : Right mesonephric vein forms the right renal vein, a tributary of IVC.</p>\n<p><strong>Extraedge:</strong></p><p>The crista terminalis forms the dividing line between the original trabeculated part of the right atrium and the smooth-walled part (sinus venarum), which originates from the right sinus horn.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The left branch of the portal vein develops from all of the following structures except:", "options": [{"label": "A", "text": "Right Vitelline Vein", "correct": true}, {"label": "B", "text": "Superior transverse anastomosis", "correct": false}, {"label": "C", "text": "Cranial part of the left vitelline vein", "correct": false}, {"label": "D", "text": "B & C", "correct": false}], "correct_answer": "A. Right Vitelline Vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right Vitelline Vein The right branch of the portal vein develops from the part of the right vitelline vein distal to the proximal ventral anastomosis. Development of Portal Vein The two vitelline veins lie on either side of the developing duodenum. They soon get interconnected by three anastomotic channels: two ventral and one dorsal. These anastomotic channels are : Proximal ventral anastomosis Middle dorsal anastomosis Distal ventral anastomosis The portal vein develops from three components: Caudal part of left vitelline vein between point at which superior mesenteric and splenic vein open, and the point where dorsal anastomosis joins the left vitelline vein. Middle dorsal anastomosis. Part of the right vitelline vein between the dorsal and proximal ventral anastomosis. The right branch of the portal vein develops from the part of the right vitelline vein distal to the proximal ventral anastomosis. The left branch of the portal vein develops from proximal ventral anastomosis, and the left vitelline vein distal to the proximal ventral anastomosis. The remaining parts of vitelline veins and distal ventral anastomosis disappear along with the left hepatocardiac channel. Development Stages of Portal Vein</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. superior transverse anastomosis The left branch of the portal vein develops from proximal ventral anastomosis and the left vitelline vein distal to the proximal ventral anastomosis. Option C. cranial part of left vitelline vein The left branch of the portal vein develops from proximal ventral anastomosis, and the left vitelline vein distal to the proximal ventral anastomosis. Option D. b & c The left branch of the portal vein develops from proximal ventral anastomosis and left vitelline vein distal to proximal ventral anastomosis, so both a and b i.e Option D also contribute in the formation of left branch of the portal vein.</p>\n<p><strong>Extraedge:</strong></p><p>The superior mesenteric and splenic veins that develop independently unite with the left vitelline vein just below dorsal anastomosis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The right hepatocardiac channel is formed by:", "options": [{"label": "A", "text": "Right vitelline vein", "correct": true}, {"label": "B", "text": "Right anterior cardiac vein", "correct": false}, {"label": "C", "text": "Right posterior cardiac vein", "correct": false}, {"label": "D", "text": "Right mesonephric vein", "correct": false}], "correct_answer": "A. Right vitelline vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right vitelline vein The proximal part of the right vitelline vein forms this right hepatocardiac channel; eventually, it becomes part of the inferior vena cava. It is joined by the right and left hepatic veins, which are derivatives of the proximal sections of each hepatic vein within the liver. The right hepatocardiac channel is formed by the right vitelline vein.</p>\n<p><strong>Highyeild:</strong></p><p>Inferior vena cava (IVC): It is the body's largest vein and develops from six components. From caudal to cranial, these components are as follows: Right posterior cardinal vein (between the transverse anastomosing channel and caudal opening of the right supra cardinal vein). It is termed the sacrocardinal segment of IVC (1). The caudal part of the right supra cardinal vein (2). Right supra cardinal–sub cardinal anastomosis (3). Right sub cardinal vein between (i) the supra cardinal–sub cardinal anastomosis and (ii) anas- tomotic channel connecting the right sub cardinal vein with right hepatocardiac channel. It is called the renal segment of the IVC (4). Anastomosing channel that connects the right sub cardinal vein to the right hepatocardiac channel (5). Right hepatocardiac channel forms the terminal segment ( hepatic segment ) of the inferior vena cava that first opens into the right horn of sinus venosus, and, after it is absorbed in the right atrium, in the right atrium itself (6). Development of Inferior vena cava Development of the inferior vena cava. Figure in the inset on the right shows 1 = Right posterior cardinal vein ( sacro- cardinal segment ). 2 = supra cardinal vein. 3 = supra cardinal–sub cardinal anastomosis. 4 = Right sub cardinal vein ( renal seg- ment ). 5 = Anastomotic channel between the sub cardinal vein and right hepatocardiac channel. 6 = Right hepatocardiac channel (hepatic segment). CIV = common iliac vein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B . right anterior cardiac vein right anterior cardiac vein forms right brachiocephalic vein Option C . right posterior cardiac vein right posterior cardiac vein cranial part forms azygos vein while caudal part contributes to the formation of IVC Option D. Right mesonephric vein right mesonephric vein forms the right renal vein, a tributary of IVC</p>\n<p><strong>Extraedge:</strong></p><p>A double inferior vena cava occurs when the left sacrocardinal vein fails to lose its connection with the left sub cardinal vein. The left common iliac vein may or may not be present, but the left gonadal vein remains normal.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Superior vena cava develops from:", "options": [{"label": "A", "text": "Right anterior cardinal vein", "correct": false}, {"label": "B", "text": "Right common cardinal vein", "correct": false}, {"label": "C", "text": "Right posterior cardinal vein", "correct": false}, {"label": "D", "text": "Both A & B", "correct": true}], "correct_answer": "D. Both A & B", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Both A & B Superior vena cava drains blood from most of the upper part of the body, and it drains blood from the right and left brachiocephalic veins. Superior vena cava: Developmentally, it consists of two parts: first and second. The first part develops from the right anterior cardinal vein caudal to the oblique transverse anastomosis. The second part develops from the right common cardinal vein. As the right common cardinal vein opens into the right horn of sinus venosus, the superior vena cava at first opens into the right horn of sinus venosus. As and when the right horn of sinus venosus is absorbed into the right atrium, the superior vena cava finally opens into the right atrium. Therefore Option A. right anterior cardinal vein and Option B. right common cardinal vein both are correct, so Option D, both A and B are correct answers.</p>\n<p><strong>Highyeild:</strong></p><p>Left superior vena cava is caused by the persistence of the left anterior cardinal vein and obliteration of the common cardinal and proximal part of the anterior cardinal veins on the right. In such a case, blood from the right is channeled toward the left by way of the brachiocephalic vein. The left superior vena cava drains into the right atrium by way of the left sinus horn, that is, the coronary sinus.</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Option: - Option C . right posterior cardinal vein The right posterior cardiac vein cranial part forms the azygos vein, while the caudal part contributes to the formation of IVC.</p>\n<p><strong>Extraedge:</strong></p><p>A double superior vena cava is characterized by the persistence of the left anterior cardinal vein and failure of the left brachiocephalic vein to form. The persistent left anterior cardinal vein, the left superior vena cava, drains into the right atrium by way of the coronary sinus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Azygos vein develops from:", "options": [{"label": "A", "text": "Right anterior cardiac vein", "correct": false}, {"label": "B", "text": "The cranial part of the right posterior cardiac vein", "correct": true}, {"label": "C", "text": "The caudal part of the right posterior cardiac vein", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "B. The cranial part of the right posterior cardiac vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The cranial part of the right posterior cardiac vein The cranial part of the right posterior cardiac vein gives rise to the azygos vein hence Option B is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>The azygos vein is formed from: The vein of the right azygos line; and The most cranial part of the right posterior cardinal vein through which it opens into the superior vena cava (formed from the right common cardinal). Azygos vein is present on the right side, and hemiazygous, accessory hemiazygos veins are present on the left side. With obliteration of the major portion of the posterior cardinal veins, the supra cardinal veins assume a greater role in draining the body wall. The 4th to 11th right intercostal veins empty into the right supra cardinal vein, which, together with a portion of the posterior cardinal vein, forms the azygos vein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Right anterior cardiac vein The right anterior cardiac vein forms brachiocephalic trunk and contributes to the formation of SVC along with the right common cardinal vein. Option C. caudal part of right posterior cardiac vein The caudal part of the right posterior cardiac vein contributes to the formation of IVC. Option D. None of the above The cranial part of the right posterior cardiac vein gives rise to the azygos vein hence Option D is the incorrect answer.</p>\n<p><strong>Extraedge:</strong></p><p>On the left, the 4th to 7th intercostal veins enter into the left supra cardinal vein, and the left supra cardinal vein, then known as the hemiazygos vein, empties into the azygos vein.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are true about the given condition except:", "options": [{"label": "A", "text": "Absence of oblique anastomosis between right and left posterior cardinal vein", "correct": true}, {"label": "B", "text": "Due to persistent left anterior cardiac vein", "correct": false}, {"label": "C", "text": "Results in the formation of SVC on the left side", "correct": false}, {"label": "D", "text": "SVC-formed drains into the coronary sinus", "correct": false}], "correct_answer": "A. Absence of oblique anastomosis between right and left posterior cardinal vein", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682527284-QTDA078007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Absence of oblique anastomosis between right and left posterior cardinal vein The given condition is – Left SVC anomaly. Left superior vena cava is caused by the persistence of the left anterior cardinal vein and obliteration of the common cardinal and proximal part of the anterior cardinal veins on the right. In such a case, blood from the right is channeled toward the left by way of the brachiocephalic vein. The left superior vena cava drains into the right atrium by way of the left sinus horn, that is, the coronary sinus.</p>\n<p><strong>Highyeild:</strong></p><p>A double superior vena cava is characterized by the persistence of the left anterior cardinal vein and failure of the left brachiocephalic vein to form. The persistent left anterior cardinal vein, the left superior vena cava, drains into the right atrium by way of the coronary sinus. Left SVC Double SVC Left superior vena cava drains into the right atrium by way of the coronary sinus [dorsal view]. Double superior vena cava. The communicating [brachiocephalic] vein between the two anterior cardinals has failed to develop [dorsal view].</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B . due to persistent left anterior cardiac vein Left superior vena cava is caused by persistence of the left anterior cardinal vein and obliteration of the common cardinal and proximal part of the anterior cardinal veins on the right. Option C . results in the formation of SVC on the left side Persistence of the left anterior cardinal vein and obliteration of the common cardinal and proximal part of the anterior cardinal veins on the right leads to the formation of left SVC. Option D . SVC formed drains into the coronary sinus The left superior vena cava drains into the right atrium through the coronary sinus.</p>\n<p><strong>Extraedge:</strong></p><p>Double inferior vena cava : Generally, the vena cava is double only below the level of the renal veins. Both channels may be present on the right side. This is caused by persistence of both the sub cardinal and supra cardinal veins below the level of the kidneys. There may be an additional channel on the left side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Right renal vein develops from:", "options": [{"label": "A", "text": "Right mesonephric vein", "correct": true}, {"label": "B", "text": "left mesonephric vein", "correct": false}, {"label": "C", "text": "left sub cardinal vein", "correct": false}, {"label": "D", "text": "Intersub cardinal anastomosis", "correct": false}], "correct_answer": "A. Right mesonephric vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right mesonephric vein Right renal vein : It develops from the vein that drains the right mesonephros. At first, it drains into the right sub cardinal vein; then as this part of the right sub cardinal vein forms part of the inferior vena cava, it drains into the inferior vena cava.</p>\n<p><strong>Highyeild:</strong></p><p>Major part of the right sub cardinal vein forms the renal segment of the inferior vena cava (on the right side), while the left sub cardinal vein forms part of the left renal vein (on the left side).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B . left mesonephric vein Option C . left sub cardinal vein Option D . intersub cardinal anastomosis Option B, C & D all contribute to the formation of the left renal vein. So all are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Left renal vein : It is longer than the right renal vein and develops from the following three sources: Mesonephric vein that drains the left mesonephros. Part of the left sub cardinal vein that receives the left mesonephric vein. Anastomotic channel between the two sub cardinal veins.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Suprarenal veins develop from", "options": [{"label": "A", "text": "Cranial part of the right and left sub cardinal vein", "correct": true}, {"label": "B", "text": "left mesonephric vein", "correct": false}, {"label": "C", "text": "left sub cardinal vein", "correct": false}, {"label": "D", "text": "Intersub cardinal anastomosis", "correct": false}], "correct_answer": "A. Cranial part of the right and left sub cardinal vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cranial part of the right and left sub cardinal vein Suprarenal veins develop from the cranial part of the right and left sub cardinal vein. The suprarenal veins are the remnants of parts of sub cardinal veins above the anastomotic channel (inter sub cardinal anastomosis). Suprarenal vein on the right side drains into IVC and suprarenal vein on left side drains into left renal vein.</p>\n<p><strong>Highyeild:</strong></p><p>The suprarenal veins are remnants of the part of the sub cardinal veins above the inter-sub cardinal anastomosis. It is clear that the termination of the right suprarenal vein in the inferior vena cava, and that of the left suprarenal vein drains in the left renal vein, is because of their developmental origin.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. left mesonephric vein Option C . left sub cardinal vein Option D . inter sub cardinal anastomosis All these options are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The testicular or ovarian veins are remnants of the parts of the sub-cardinal veins below the inter sub-cardinal anastomosis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are sources of IVC except:", "options": [{"label": "A", "text": "Right posterior cardinal vein", "correct": false}, {"label": "B", "text": "Left anterior cardinal vein", "correct": true}, {"label": "C", "text": "Right supra cardinal vein", "correct": false}, {"label": "D", "text": "Right sub cardinal vein", "correct": false}], "correct_answer": "B. Left anterior cardinal vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left anterior cardinal vein The anterior cardinal veins begin their embryological development as symmetric venous channels draining blood from the cranial structures of the embryo. They anastomose with the posterior cardinal veins inferiorly to form the common cardinal veins (ducts of Cuvier), which drain into the sinus venosus . At approximately 8 weeks of gestation, the left brachiocephalic vein forms from an anastomosis between the thymicothyroic veins and connects the left and right anterior cardinal veins. After this left-right connection forms, asymmetry develops when the caudal portion of the left anterior cardinal vein begins to involute, which redirects blood flow to the proximal right anterior cardinal vein, which persists to become the right-sided superior vena cava (SVC). The caudal portion of the left anterior cardinal artery forms the oblique ligament and vein of Marshall after involution. The more cranial portions of the bilateral anterior cardinal veins persist and form the internal jugular vein . During the course of their development and involution, the anterior cardinal veins form multiple normal permanent structures, as well as potentially some anomalous structures.</p>\n<p><strong>Highyeild:</strong></p><p>Inferior vena cava (IVC): It is the largest vein of the body and develops from six components. From caudal to cranial, these components are as follows: Right posterior cardinal vein (between the transverse anastomosing channel and caudal opening of the right supra cardinal vein). It is termed the sacrocardinal segment of IVC (1). The caudal part of the right supra cardinal vein (2). Right supra cardinal–sub cardinal anastomosis (3) Right sub cardinal vein between (i) the supra cardinal–sub cardinal anastomosis and (ii) anas- tomotic channel connecting the right sub cardinal vein with right hepatocardiac channel. It is called the renal segment of the IVC (4). Anastomosing channel that connects the right sub cardinal vein to the right hepatocardiac channel (5). Right hepatocardiac channel forms terminal segment ( hepatic segment ) of the inferior vena cava that first opens into right horn of sinus venosus, and, after the right horn is absorbed in the right atrium, in the right atrium itself (6). Development of Inferior vena cava Development of the inferior vena cava. Figure in the inset on the right shows 1 = Right posterior cardinal vein ( sacro- cardinal segment ). 2 = supra cardinal vein. 3 = supra cardinal–sub cardinal anastomosis. 4 = Right sub cardinal vein ( renal seg- ment ). 5 = Anastomotic channel between sub cardinal vein and right hepatocardiac channel. 6 = Right hepatocardiac channel (hepatic segment). CIV = common iliac vein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. right posterior cardinal vein Option C. right supra cardinal vein Option D. right sub cardinal vein all sources of IVC.</p>\n<p><strong>Extraedge:</strong></p><p>Developmental Variation of Left anterior cardinal vein Failure of the left anterior cardinal vein to involute is the most common developmental variation in the central venous system with an incidence of 0.3%. Failure of the left anterior cardinal vein to involute results in a left-sided superior vena cava, and in 8% of these cases, drainage of the left-sided superior vena cava into the left atrium. Failure of involution is usually related to a failure of the anastomosis of the left and right anterior cardinal veins through the brachiocephalic vein.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are tributaries and arise from vitelline veins except:", "options": [{"label": "A", "text": "Superior mesenteric vein", "correct": false}, {"label": "B", "text": "Splenic vein", "correct": false}, {"label": "C", "text": "Portal vein", "correct": false}, {"label": "D", "text": "SVC", "correct": true}], "correct_answer": "D. SVC", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>SVC Right and left brachiocephalic veins join to form SVC. Superior vena cava develops from the Right anterior cardinal vein and right common cardinal vein.</p>\n<p><strong>Highyeild:</strong></p><p>The most common anatomical variation is a persistent left superior vena cava. In persons with a persistent left superior vena cava, the right superior vena cava may be normal, small or absent, with or without an anterior communicating vein. This variation is present in less than 0.5% of the general population, but in up to 10% in patients with congenital heart disease .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Superior mesenteric vein The superior mesenteric vein (SMV) is a major venous tributary of the abdominal cavity. Embryologically derived in association with the vitelline vein, the superior mesenteric vein lies lateral to the superior mesenteric artery (SMA) and serves to drain the vast majority of the organs of the abdominal cavity. Option C. Portal vein Development of Portal Vein The two vitelline veins lie on either side of the developing duodenum. They soon get interconnected by three anastomotic channels: two ventral and one dorsal. These anastomotic channels are: Proximal ventral anastomosis Middle dorsal anastomosis Distal ventral anastomosis The portal vein develops from three components: Caudal part of the left vitelline vein between the point at which superior mesenteric and splenic vein open, and the point where dorsal anastomosis joins the left vitelline vein. Middle dorsal anastomosis. Part of the right vitelline vein between the dorsal and proximal ventral anastomosis. The right branch of the portal vein develops from the part of the right vitelline vein distal to proximal ventral anastomosis. The left branch of the portal vein develops from proximal ventral anastomosis and the left vitelline vein distal to the proximal ventral anastomosis. Remaining parts of vitelline veins and distal ventral anastomosis disappear along with the left hepatocardiac channel. Development stages of Portal vein Option B. Splenic Vein The superior mesenteric and splenic veins that develop independently unite with the left vitelline vein just below dorsal anastomosis.</p>\n<p><strong>Extraedge:</strong></p><p>Development of Common iliac veins: Right common iliac vein is derived from the most caudal part of the right posterior cardinal vein. Left common iliac vein represents the anastomosis between the two posterior cardinal veins.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are true about double IVC except:", "options": [{"label": "A", "text": "Due to the persistence of the left supra cardinal vein", "correct": false}, {"label": "B", "text": "Double inferior vena cava occurs when the left sacrocardinal vein fails to lose its connection with the left sub cardinal vein", "correct": false}, {"label": "C", "text": "Both channels may be present on the right side.", "correct": false}, {"label": "D", "text": "Due persistent left anterior cardinal vein", "correct": true}], "correct_answer": "D. Due persistent left anterior cardinal vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Due persistent left anterior cardinal vein Usually, after the formation of an oblique anastomosis between both anterior cardinal veins, the caudal part of the left anterior cardinal vein disappears. If oblique anastomosis is not formed, then the caudal part of the left Anterior cardinal vein will persist and give rise to double SVC.</p>\n<p><strong>Highyeild:</strong></p><p>Duplication of the IVC occurs because the left supra cardinal vein fails to regress early in gestation resulting in large veins on both sides of the aorta that usually joins anterior to the level of the renal arteries to become the suprarenal IVC.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. due to persistent of left supra cardinal vein Double IVC is caused by persistence of both the sub cardinal and supra cardinal veins below the level of the kidneys Option B. Double inferior vena cava occurs when the left sacrocardinal vein fails to lose its connection with the left sub cardinal vein. A double inferior vena cava occurs when the left sacrocardinal vein fails to lose its connection with the left sub cardinal vein. The left common iliac vein may or may not be present, but the left gonadal vein remains as in normal conditions. Option C. Both channels may be present on the right side. Generally, the vena cava is double only below the level of the renal veins. Both channels may be present on the right side.</p>\n<p><strong>Extraedge:</strong></p><p>Absence of inferior vena cava : In this condition, the anastomosing channel between the right sub cardinal vein and right hepato-cardiac channel fails to develop. The cranial part of the right sub cardinal vein, which normally disappears, persists and carries the blood from the inferior vena cava to the superior vena cava. The hepatic veins directly open into the right atrium at the site of the inferior vena cava.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Gonadal vein develops from:", "options": [{"label": "A", "text": "Right Mesonephric Vein", "correct": false}, {"label": "B", "text": "Left mesonephric vein", "correct": false}, {"label": "C", "text": "Cranial part of sub cardinal vein", "correct": false}, {"label": "D", "text": "Caudal part of sub cardinal vein", "correct": true}], "correct_answer": "D. Caudal part of sub cardinal vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Caudal part of sub cardinal vein Right Gonadal vein drains into IVC and the left Gonadal vein drains into the left renal vein. The gonadal vein develops from the caudal part of the sub cardinal vein.</p>\n<p><strong>Highyeild:</strong></p><p>The testicular and ovarian veins are the remnants of parts of sub cardinal veins below the inter sub cardinal anastomosis. This explains why right suprarenal and right gonadal veins open into the vena cava while left suprarenal and left gonadal veins open into the left renal vein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A: right mesonephric vein forms right renal vein Option B: left mesonephric vein along with left sub cardinal vein and inter sub cardinal anastomosis forms left renal vein Option C: cranial part of sub cardinal vein forms suprarenal vein</p>\n<p><strong>Extraedge:</strong></p><p>Suprarenal veins : The suprarenal veins are the remnants of parts of sub cardinal veins above the anastomotic channel (inter sub cardinal anastomosis).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Right common iliac vein develops as:", "options": [{"label": "A", "text": "Continuation of right posterior cardinal vein", "correct": true}, {"label": "B", "text": "Continuation of left posterior cardinal vein", "correct": false}, {"label": "C", "text": "Cranial part of sub cardinal vein", "correct": false}, {"label": "D", "text": "Caudal part of sub cardinal vein", "correct": false}], "correct_answer": "A. Continuation of right posterior cardinal vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Continuation of right posterior cardinal vein Common iliac veins of both sides join to form IVC. Right common iliac vein develops as a continuation of the right posterior cardinal vein. Right common iliac vein : It develops from the caudal part of the right posterior cardinal vein below the transverse anastomosis between the two posterior cardinal veins.</p>\n<p><strong>Highyeild:</strong></p><p>Left common iliac vein : It develops from the transverse anastomosis between the two posterior cardinal veins and part of the left posterior cardinal vein below the anastomosis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B: left posterior cardinal vein continues as left common iliac vein. Option C: Cranial part of sub cardinal vein forms suprarenal vein. Option D: Gonadal vein develops from the caudal part of the sub cardinal vein.</p>\n<p><strong>Extraedge:</strong></p><p>External iliac veins : On each side, the external iliac vein develops from one of the intersegmental veins in the region of the lower limb bud. It drains the lower limb and joins the caudal end of the posterior cardinal vein of the respective side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following are formed from vitelline veins, EXCEPT:", "options": [{"label": "A", "text": "Superior vena cava", "correct": true}, {"label": "B", "text": "Portal vein", "correct": false}, {"label": "C", "text": "Inferior vena cava", "correct": false}, {"label": "D", "text": "Superior mesenteric vein", "correct": false}], "correct_answer": "A. Superior vena cava", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior vena cava Right and left brachiocephalic veins join to form SVC. The superior vena cava is formed by the right common cardinal vein and the proximal portion of the right anterior cardinal vein. The anterior cardinal veins provide the primary venous drainage of the head during the fourth week of development and ultimately form the internal jugular veins.</p>\n<p><strong>Highyeild:</strong></p><p>The anastomosis between the anterior cardinal veins develops into the left brachiocephalic vein. Most of the blood from the left side of the head and the left upper extremity is then channelled to the right.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option C. Inferior vena cava The vitelline veins, right and left, arise from ramifications on the yolk sac and pass in the splanchnopleure to the sinus venosus. With the reduction of the left sinus horn, blood from the left side of the liver is rechanneled toward the right, resulting in an enlargement of the right vitelline vein (right hepatocardiac channel). Ultimately, the right hepatocardiac channel forms the hepatocardiac portion of the inferior vena cava. Option B . Portal vein The proximal part of the left vitelline vein disappears. The anastomotic network around the duodenum develops into a single vessel, the portal vein. Option D. Superior mesenteric vein The superior mesenteric vein, which drains the primary intestinal loop, derives from the right vitelline vein. The distal portion of the left vitelline vein also disappears.</p>\n<p><strong>Extraedge:</strong></p><p>Preureteric vena cava: In this condition, the right ureter passes behind the inferior vena cava ( retrocaval ureter ). It occurs when the infrarenal part of IVC develops from the sub cardinal vein that lies anterior to the ureter instead of the supra cardinal vein that lies posterior to the ureter.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following forms a portal vein?", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": true}], "correct_answer": "D. D", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682527316-QTDA078016IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>D Sinus venosus – It forms the entry point for the venous system. Left common cardinal vein Left umbilical vein Left vitelline vein Explanation Before entering the sinus venosus , the Vitelline veins form a plexus around the duodenum and pass through the septum transversum . The liver cords growing into the septum interrupt the course of the veins, and an extensive vascular network, the hepatic sinusoids, forms. With the reduction of the left sinus horn, blood from the left side of the liver is rechanneled toward the right, resulting in an enlargement of the right vitelline vein (right hepatocardiac channel). Ultimately, the right hepatocardiac channel forms the hepatocardiac portion of the inferior vena cava. The proximal part of the left vitelline vein disappears. The anastomotic network around the duodenum develops into a single vessel, the portal vein. Stages of development of Portal vein</p>\n<p><strong>Highyeild:</strong></p><p>With the increase of the placental circulation, a direct communication forms between the left umbilical vein and the right hepatocardiac channel, the ductus venosus . This vessel bypasses the sinusoidal plexus of the liver. After birth, the left umbilical vein and ductus venosus are obliterated and form the ligamentum teres hepatis and ligamentum venosum, respectively.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A- Sinus venosus – It forms the entry point for the venous system. Option B- Left common cardinal vein Option C- Left umbilical vein The source of development of Portal vein is left vitelline vein, so Options A,B and C are all incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The superior mesenteric vein, which drains the primary intestinal loop, derives from the right vitelline vein. The distal portion of the left vitelline vein also disappears.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 26 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "An attending surgeon during surgery at the root of the neck, cautions her resident to locate important structures which need to be protected. One of these is the phrenic nerve, responsible for the innervation of the diaphragm and thus, respiration. The phrenic nerve can be positively identified by which of the following anatomical relationships?", "options": [{"label": "A", "text": "It is found immediately between the common carotid artery and the internal jugular vein", "correct": false}, {"label": "B", "text": "It lies immediately between the esophagus and the trachea", "correct": false}, {"label": "C", "text": "It lies on the scalenus medius muscle", "correct": false}, {"label": "D", "text": "The suprascapular and transverse cervical arteries cross over it anteriorly", "correct": true}], "correct_answer": "D. The suprascapular and transverse cervical arteries cross over it anteriorly", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The suprascapular and transverse cervical arteries cross over it anteriorly Phrenic Nerve is crossed anteriorly by the inferior belly of the omohyoid muscle, the transverse cervical and suprascapular arteries. Phrenic nerve anteriorly crossed by Suprascapular and transverse cervical arteries</p>\n<p><strong>Highyeild:</strong></p><p>The phrenic nerve originates in the phrenic motor nucleus in the ventral horn of the cervical spinal cord. It descends obliquely with the internal jugular vein across the anterior scalene, deep to the prevertebral layer of deep cervical fascia and the transverse cervical and suprascapular arteries.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. It is found immediately between the common carotid artery and the internal jugular vein The vagus (tenth cranial) nerve, not the phrenic nerve, is located between the common carotid artery and the internal jugular vein. Option B. It lies immediately between the esophagus and the trachea The recurrent laryngeal branch from the vagus nerve wraps around the right subclavian artery and courses cranially between the esophagus and the trachea. Option C. It lies on the scalenus medius muscle At the root of the neck, the phrenic nerve (C3, C4, C5) lies on the scalenus anterior muscle, not the scalenus medius.</p>\n<p><strong>Extraedge:</strong></p><p>On the left, the phrenic nerve crosses anterior to the first part of the subclavian artery. On the right, it lies on the anterior scalene muscle and crosses anterior to the 2nd part of the subclavian artery. On both sides, the phrenic nerve usually runs posterior to the subclavian vein as it enters the thorax where it runs anterior to the root of the lung and between the fibrous pericardium and mediastinal parietal pleura.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 2-day-old infant is diagnosed with incomplete division of the foregut into respiratory and digestive portions. The most common congenital condition characteristic of this description:", "options": [{"label": "A", "text": "Esophageal Atresia", "correct": true}, {"label": "B", "text": "Esophageal achalasia", "correct": false}, {"label": "C", "text": "Tracheoesophageal fistula", "correct": false}, {"label": "D", "text": "Congenital diaphragmatic hernia", "correct": false}], "correct_answer": "A. Esophageal Atresia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Esophageal Atresia Esophageal atresia is often the result of an incomplete division of the tracheoesophageal septum, thus causing an absence of, or blind-ending of, the esophagus.</p>\n<p><strong>Highyeild:</strong></p><p>Esophageal atresia is a congenital medical condition (birth defect) that causes the esophagus to end in a blind-ended pouch rather than connecting normally to the stomach. It is characterized anatomically by a congenital obstruction of the esophagus with interruption of the continuity of the esophageal wall. Esophageal atresia</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Esophageal achalasia Achalasia occurs when nerves in the esophagus become damaged . As a result, the esophagus becomes paralyzed and dilated over time and eventually loses the ability to squeeze food down into the stomach. Food then collects in the esophagus, sometimes fermenting and washing back up into the mouth, which can taste bitter. Option C. Tracheoesophageal fistula Though similar to esophageal atresia, a tracheoesophageal fistula is an atypical connection between the trachea and the esophagus. Option D. Congenital diaphragmatic hernia Congenital diaphragmatic hernia (CDH) occurs when there is a hole in the diaphragm, which is the thin sheet of muscle separating the chest from the abdomen. When this gap forms during a fetus's development in the womb, the bowel, stomach, or even the liver can move into the chest cavity.</p>\n<p><strong>Extraedge:</strong></p><p>Any attempt at feeding Esophageal atresia-affected babies could cause aspiration pneumonia as the milk collects in the blind pouch and overflows into the trachea and lungs. Furthermore, a fistula between the lower esophagus and trachea may allow stomach acid to flow into the lungs and cause damage. Because of these dangers, the condition must be treated as soon as possible after birth.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An unconscious 2-month-old infant came to casualty after an automobile collision. An emergency tracheostomy is performed. Which of the following structures is most commonly at high risk of injury during this procedure?", "options": [{"label": "A", "text": "Left Brachiocephalic Vein", "correct": true}, {"label": "B", "text": "Left common carotid artery", "correct": false}, {"label": "C", "text": "Vagus nerve", "correct": false}, {"label": "D", "text": "Phrenic nerve", "correct": false}], "correct_answer": "A. Left Brachiocephalic Vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left Brachiocephalic Vein In a tracheotomy, an incision is made at the level of the sixth cervical vertebra, near the cricoid cartilage. The left brachiocephalic vein passes across the trachea immediately anterior to the brachiocephalic trunk. The brachiocephalic vein is the most superficial structure and thus the most likely to be damaged.</p>\n<p><strong>Highyeild:</strong></p><p>The brachiocephalic veins, also referred to as the innominate veins, are large venous structures located within the thorax and originate from the union of the subclavian vein with the internal jugular vein. The left and right brachiocephalic vein join to form the superior vena cava on the right side of the upper chest . The left brachiocephalic vein begins posterior to the medial end of the left clavicle. It crosses to the right, moving in a slightly inferior direction, and joins with the right brachiocephalic vein to form the superior vena cava posterior to the lower edge of the right first costal cartilage close to the right sternal border. Venous tributaries include the vertebral, first posterior intercostal, left superior intercostal, inferior thyroid, and internal thoracic veins. It may also receive thymic and pericardia! veins. The left brachiocephalic vein crosses the midline posterior to the manubrium in the adult. In infants and children, the left brachiocephalic vein rises above the superior border of the manubrium and therefore is less protected.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options B, C, and D are incorrect because, The left common carotid artery, the vagus nerve, and the phrenic nerve are not situated near the midline incision of the tracheotomy.</p>\n<p><strong>Extraedge:</strong></p><p>The thoracic duct is located posterior and lateral to the esophagus and the trachea and is not likely to be damaged during a tracheotomy, other than the intentional opening made in it.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A newborn female infant cannot swallow and exhibits persistent drooling, and aspiration or regurgitation of food after attempted feedings. When the infant strains, coughs, or cries, the stomach inflates, elevating the diaphragm and making respiration more difficult. The patient is diagnosed with congenital esophageal atresia at the cervical level, necessitating surgical repair. During the surgery, the blood supply of the esophagus must be carefully isolated to protect it from injury. Which of the following arteries supplies the esophagus at cervical levels?", "options": [{"label": "A", "text": "Bronchial Artery", "correct": false}, {"label": "B", "text": "Inferior thyroid artery", "correct": true}, {"label": "C", "text": "Internal thoracic artery", "correct": false}, {"label": "D", "text": "Left inferior gastric artery", "correct": false}], "correct_answer": "B. Inferior thyroid artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior thyroid artery The inferior thyroid artery provides for the majority of the blood supply of the esophagus at cervical levels. Esophagus blood supply can be assisted by branches from the common carotid, subclavian, vertebral, ascending pharyngeal, superficial cervical, and costocervical arteries.</p>\n<p><strong>Highyeild:</strong></p><p>The inferior thyroid artery is an artery in the neck. It arises from the thyrocervical trunk and passes upward, in front of the vertebral artery and longus colli muscle. It then turns medially behind the carotid sheath and its contents, and also behind the sympathetic trunk, the middle cervical ganglion resting upon the vessel.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option. A & C. Bronchial Artery & Internal thoracic artery The bronchial arteries (choice A) supply the thoracic portion of the esophagus and may be assisted in the lower part by branches of the internal thoracic artery (choice C). Option D. Left inferior gastric artery The abdominal portion of the esophagus is vascularized by branches from the left inferior gastric artery and left inferior phrenic artery.</p>\n<p><strong>Extraedge:</strong></p><p>The branches of the inferior thyroid artery are the inferior laryngeal, the oesophageal, the tracheal, the ascending cervical, and the pharyngeal arteries.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A male diabetic patient is brought to the physician. The patient exhibits angina, bloating, GERD, early satiety, and nausea. He has a history of gastric bypass surgery. Examination shows the presence of bezoars in the stomach with an increased bacterial count. Which of the following structures is associated with this disease?", "options": [{"label": "A", "text": "Lower Esophageal Sphincter", "correct": false}, {"label": "B", "text": "Esophagus", "correct": false}, {"label": "C", "text": "Pyloric sphincter", "correct": true}, {"label": "D", "text": "Oxyntic cells", "correct": false}], "correct_answer": "C. Pyloric sphincter", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pyloric sphincter The pyloric sphincter is predominantly involved in gastroparesis even though it is due to antral hypomotility. The Chyme accumulates in the stomach and gets hardened to form bezoars. Prolonged accumulation ferments the contents and increases the bacterial content. The damage to the vagus nerve causes pyloric malfunction and antral hypomotility. Hence, it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>The clinical vignette comes to a diagnosis of gastroparesis. The common symptoms include early satiety, nausea, vomiting, bloating, GERD, malnutrition, and lower blood sugar level. In this disease, there is a decreased outflow of Chyme from the stomach due to damage to the vagus nerve . The vagus nerve could have been damaged either due to diabetes or during gastric bypass surgery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Lower esophageal sphincter is involved in the passage of bolus from the esophagus to the stomach. It malfunctions in GERD and doesn’t cause bezoar formation. Hence, it is the wrong answer. Option: B. Esophagus is a muscular tube for conveying bolus to the Disease in the esophagus doesn’t cause bezoar formation and increased bacterial count. Hence, it is the wrong answer. Option: D. Oxyntic cells are the cells of the mucosal layer of the stomach wall that produce hydrochloric acid and intrinsic factor. Diseases of these cells either cause pernicious anemia (Vit. B12 deficiency) or gastric and duodenal ulcer (increased HCl production). Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Gastroparesis , also called delayed gastric emptying , is a medical disorder consisting of weak muscular contractions (peristalsis) of the stomach, resulting in food and liquid remaining in the stomach for a prolonged period of time. Stomach contents thus exit more slowly into the duodenum of the digestive tract. This can result in irregular absorption of nutrients, inadequate nutrition, and poor glycemic control.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "As a resident of surgery, you were prepared to assist in a transhiatal esophageal surgery, your Senior doing surgery has injured a structure, injury was suspected only in the postoperative period where a milky white drain was seen in the chest drain. This structure belongs to the posterior mediastinum what structure has been involved:", "options": [{"label": "A", "text": "Thymus", "correct": false}, {"label": "B", "text": "Mediastinal branch of internal thoracic artery", "correct": false}, {"label": "C", "text": "Thoracic duct", "correct": true}, {"label": "D", "text": "Pulmonary trunk", "correct": false}], "correct_answer": "C. Thoracic duct", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thoracic duct During surgery of the esophagus thoracic duct most commonly involved it drains into the left internal jugular vein and left subclavian vein, its injury leads to a milky white discharge from the chest and abdominal drain which is a chylous drainage. The thoracic duct drains lymph from the entire left side of the body and also from the right lower limb. The thoracic duct is the content of the posterior mediastinum.</p>\n<p><strong>Highyeild:</strong></p><p>The posterior mediastinum contains the descending thoracic aorta (on the left side of the spine), the esophagus (median, but positioned anterior to the aorta inferiorly), and, more posteriorly, the azygos and hemiazygos venous systems, the thoracic duct, lymph nodes, right and left sympathetic chains and thoracic splanchnic nerves .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A: Superior mediastinum-triangular space is occupied by the thymus or its remnants. The superior mediastinum accommodates the trachea, esophagus, aortic arch, brachiocephalic trunk, left common carotid, and subclavian arteries (the vertebral artery sometimes arises from the aortic arch between them), the internal thoracic arteries, the left superior intercostal, hemiazygos, internal thoracic and inferior thyroid veins, and numerous lymph nodes, including those from the tracheobronchial, paratracheal and brachiocephalic groups. Option B: Anterior mediastinum-contains loose connective tissue, the sternopericardial ligaments, a few lymph nodes, the mediastinal branches of the internal thoracic artery, and sometimes part of the thymus gland or its degenerated remains. Option D: Middle mediastinum contains pericardium, heart, and ascending aorta, the inferior, intrapericardial half of the superior vena cava (receiving the azygos venous arch posteriorly), the tracheal bifurcation and main bronchi, the pulmonary trunk, right and left pulmonary vasculature, phrenic nerves, the deep part of the cardiac plexus and the tracheo- bronchial lymph nodes.</p>\n<p><strong>Extraedge:</strong></p><p>Posterior mediastinum (or paravertebral compartment ) is a potential space along the paravertebral sulci. It is conceptually considered a portion of the inferior mediastinum, and separated from the middle mediastinal compartment and the remainder of the extrapleural intrathoracic cavity by arbitrary lines. The posterior mediastinum is continuous with the retropharyngeal space via the posterior part of the superior mediastinum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient was brought to your OPD with a complaint of a burning sensation in the chest after eating spicy food and you diagnosed it as a case of (GERD). As you are teaching your students in your OPD you ask them if there are 3 constrictions in the esophagus which help prevent acid reflux among them which structure is in relation with the constriction at 23cm?", "options": [{"label": "A", "text": "Aortic Arch", "correct": true}, {"label": "B", "text": "Left principal bronchus", "correct": false}, {"label": "C", "text": "Esophagus pass diaphragm", "correct": false}, {"label": "D", "text": "Pharynx joins the upper end", "correct": false}], "correct_answer": "A. Aortic Arch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Aortic Arch Aortic arch - Esophagus is crossed anteriorly by the aortic arch (23 cm from the incisor teeth, as measured during oesophagoscopy), This is responsible for one of the esophageal constrictions.</p>\n<p><strong>Highyeild:</strong></p><p>Esophageal constriction level</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Esophagus is crossed by the left principal bronchus (28 cm from the incisor teeth, as measured during esophagoscopy). Option C. Esophagus as it passes through the diaphragm (40 cm from the incisor teeth, as measured during esophagoscopy). Option D. Pharynx where join with the upper end 15 cm from the incisor teeth, as measured during oesophagoscopy).</p>\n<p><strong>Extraedge:</strong></p><p>The esophagus is 23-37 cm long with a diameter of 1-2 cm and is divided into three parts: Cervical: continuous with the hypopharynx, commences at the lower border of the cricoid cartilage (at the level of C5/6) or cricopharyngeus muscle. Thoracic: from the superior thoracic aperture (T1) to the esophageal hiatus (T10) in the diaphragm which covers the inferior thoracic aperture. Abdominal: from oesophageal hiatus and is continuous with the cardia of the stomach at the gastro-esophageal junction.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following belongs to the posterior mediastinum?", "options": [{"label": "A", "text": "Aortic Arch", "correct": false}, {"label": "B", "text": "Descending thoracic aorta", "correct": true}, {"label": "C", "text": "Tracheal bifurcation", "correct": false}, {"label": "D", "text": "Mediastinal branch of internal thoracic artery", "correct": false}], "correct_answer": "B. Descending thoracic aorta", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Descending thoracic aorta The posterior mediastinum contains the descending thoracic aorta (on the left side of the spine), the esophagus (median, but positioned anterior to the aorta inferiorly), and, more posteriorly, the azygos and hemiazygos venous systems, the thoracic duct, lymph nodes, right and left sympathetic chains and thoracic splanchnic nerves. Descending thoracic aorta gives rise to lumbar arteries on either side.</p>\n<p><strong>Highyeild:</strong></p><p>Contents of Posterior Mediastinum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Superior mediastinum is a triangular space occupied by the thymus or its remnants. The superior mediastinum accommodates the trachea, esophagus, aortic arch, brachiocephalic trunk, left common carotid and subclavian arteries (the vertebral artery sometimes arises from the aortic arch between them), the internal thoracic arteries, the left superior intercostal, hemiazygos, internal thoracic and inferior thyroid veins, and numerous lymph nodes, including those from the tracheobronchial, paratracheal and brachiocephalic groups. Option C. Middle mediastinum contains pericardium, heart, and ascending aorta, the inferior, intrapericardial half of the superior vena cava (receiving the azygos venous arch posteriorly), the tracheal bifurcation and main bronchi, the pulmonary trunk, right and left pulmonary vasculature, phrenic nerves, the deep part of the cardiac plexus and the tracheo- bronchial lymph nodes. Option D. Anterior mediastinum contains loose connective tissue, the sternopericardial ligaments, a few lymph nodes, the mediastinal branches of the internal thoracic artery, and sometimes part of the thymus gland or its degenerated remains.</p>\n<p><strong>Extraedge:</strong></p><p>Mediastinum can be divided into parts based on their relationship to the fibrous pericardium: Superior mediastinum: above the upper level of the pericardium and plane of Ludwig. Inferior mediastinum: below the plane of Ludwig anterior mediastinum: anterior to the pericardium middle mediastinum: within the pericardium posterior mediastinum: posterior to the pericardium.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient was brought to the clinic at night with complaints of following eating high spicy food for a challenge he started to experience a burning sensation in his chest which does not relieve by drinking cold water, and buttermilk. You diagnosed it as a case of GERD and treated it with an antacid. Which among the following is a major anti-reflux factor?", "options": [{"label": "A", "text": "Folds of gastric mucosa present at the gastro-oesophageal junction", "correct": false}, {"label": "B", "text": "The angle of the cardiac orifice (angle of His)", "correct": false}, {"label": "C", "text": "Tonically contracted, specialized, thickened intrinsic circular smooth muscle of the lower esophagus, which is reinforced by the extrinsic encircling fibers of the right diaphragmatic crus", "correct": true}, {"label": "D", "text": "Length of the abdominal esophagus, which is buttressed externally by pads of adipose tissue at and below the level of the esophageal hiatus", "correct": false}], "correct_answer": "C. Tonically contracted, specialized, thickened intrinsic circular smooth muscle of the lower esophagus, which is reinforced by the extrinsic encircling fibers of the right diaphragmatic crus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tonically contracted, specialized, thickened intrinsic circular smooth muscle of the lower esophagus, which is reinforced by the extrinsic encircling fibers of the right diaphragmatic crus Anti-reflux factors - Tonically contracted, specialized, thickened intrinsic circular smooth muscle of the lower esophagus, which is reinforced by the extrinsic encircling fibers of the right diaphragmatic crus. This helps to prevent gastric reflux into the esophagus. Together, they exert radial pressure on the lower 2–4 cm of the esophagus, creating an effective high-pressure zone (HPZ) that can be measured by electromyography or manometry.</p>\n<p><strong>Highyeild:</strong></p><p>Gastroesophageal reflux disease ( GERD ) or gastro-oesophageal reflux disease ( GORD ) is one of the upper gastrointestinal chronic diseases in which stomach content persistently and regularly flows up into the esophagus, resulting in symptoms and/or complications. Symptoms include dental corrosion, dysphagia, heartburn, odynophagia, regurgitation, non-cardiac chest pain, and extraesophageal symptoms such as chronic cough, hoarseness, reflux-induced laryngitis, or asthma .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Folds of gastric mucosa present at the gastro-oesophageal junction form a mucosal rosette that helps to create a fluid- and gas-tight seal from the basal tonic contraction of the muscular wall of the lower esophagus. Option B. The angle of the cardiac orifice (angle of His), is formed, in part, by the pull of the oblique fibers of the innermost layer of gastric smooth muscle, thereby constituting a type of ‘flap valve’. Option D. Length of the abdominal esophagus, which is buttressed externally by pads of adipose tissue at and below the level of the esophageal hiatus.</p>\n<p><strong>Extraedge:</strong></p><p>In the long term, in cases of GERD which are not treated, complications such as esophagitis, esophageal stricture, and Barrett's esophagus may arise.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient is a known case of GERD who is on medication. Now he came with a complaint of aggravation of symptoms even with food he used to take before. The surgeon who performed the endoscopy saw changes in the lower esophagus so he did a biopsy of the esophagus to rule out adenocarcinoma. Under microscopy in which of the following layers we can see Langerhans cell?", "options": [{"label": "A", "text": "Mucosal Epithelium", "correct": true}, {"label": "B", "text": "Lamina propria", "correct": false}, {"label": "C", "text": "Muscularis mucosa", "correct": false}, {"label": "D", "text": "Sub mucosa", "correct": false}], "correct_answer": "A. Mucosal Epithelium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Mucosal Epithelium The mucosal epithelium contains Langerhans cells . Langerhans cells are present in the esophageal epithelium. They are immature dendritic cells and resemble those found in the epidermis. They perform similar antigen-processing and antigen-presenting roles, which are important in the immunostimulation of naïve T cells and mucosal defense.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Lamina propria: The oesophageal lamina propria contains scattered groups of mucosa-associated lymphoid tissue (MALT), especially prominent near the gastro-oesophageal junction. Small tubular mucous glands occur in this region and also at the esophago-pharyngeal junction Option C. Muscularis mucosae: The muscularis mucosae is composed mainly of longitudinal smooth muscle and forms a thin sheet near the epithelium, the contours of which it follows closely. At the pharyngeal end of the esophagus, it may be absent or represented only by sparse, scattered bundles; below this, it becomes progressively thicker. The longitudinal orientation of its cells changes to a more plexiform arrangement near the gastro-oesophageal junction. The ducts of the oesophageal glands pierce the muscularis mucosae. Option D. Sub mucosa: The submucosa loosely connects the mucosa and the muscularis externa, penetrating the longitudinal ridges of the oesophageal lumen. It contains larger blood vessels, nerves, and mucous glands. Its elastic fibers aid the closure of the oesophageal lumen after peristaltic dilation.</p>\n<p><strong>Extraedge:</strong></p><p>Barrett’s esophagus, or columnar lined esophagus, is an acquired condition that results from chronic gastro-oesophageal reflux. It is characterized by the metaplastic replacement of the normal squamous epithelium of the lower esophagus by columnar epithelium. The diagnosis of Barrett’s esophagus is made on endoscopy, but it has to be confirmed by the histological examination of biopsies, which show the characteristic incomplete intestinal metaplasia (also called “specialized” mucosa). Barrett’s esophagus</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient was operated on for esophageal repair through a transhiatal route. While the operation was being performed your senior doctor asked you which of the following structures which vertebral column at the level of T5 and drain into left IJV and left subclavian most commonly involved in esophageal surgery?", "options": [{"label": "A", "text": "Thoracic Duct", "correct": true}, {"label": "B", "text": "Azygos vein", "correct": false}, {"label": "C", "text": "Hemiazygos vein", "correct": false}, {"label": "D", "text": "Right brachiocephalic vein", "correct": false}], "correct_answer": "A. Thoracic Duct", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thoracic Duct From the superior aspect of the cisterna chyli, the thoracic duct p asses through the aortic hiatus and enters the posterior mediastinum, lying to the right between the aorta and the azygos vein up to the level of the fifth thoracic vertebra, where it typically crosses over the vertebral column posterior to the esophagus. The thoracic duct continues upwards, first posterior to the aortic arch adjacent to the left side of the esophagus, then posterior to the left subclavian artery in the superior mediastinum. It next arches over the subclavian artery and descends anteriorly to empty into the venous circulation in the region of the left jugular and subclavian veins. The thoracic duct drains lymph from the left side of the body and the right lower limb.</p>\n<p><strong>Highyeild:</strong></p><p>Thoracic duct originates anterior to the first or second lumbar vertebrae, where the intestinal and two lumbar lymph trunks join to form the cisterna chyli. (both the thoracic duct and the cisterna chyli are variable in their origin, course and length; the latter is even more variable in width and shape than the thoracic duct.) It gets most commonly injured in esophagus surgery. Course of Thoracic duct</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Azygous vein - drain into svc Formative tributaries of the azygos vein is the right subcostal vein, right lumbar ascending vein, right lumbar azygous vein To azygous vein right side 5th to 12 intercoastal vein drain Option C. The Hemiazygos vein is on the left side it drains into the azygos vein 9th to 12th intercostal vein drain into this vein. Option D . Right and left brachiocephalic vein form into superior vena cava To the right brachiocephalic right side 1st posterior intercostal vein get drained.</p>\n<p><strong>Extraedge:</strong></p><p>Tributaries of the thoracic duct</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient came in with a complaint of dysphagia and chest pain. A barium swallow shows abnormal esophageal contraction. Which among the following images shows obliteration of the esophageal lumen due to segmental contraction?", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": true}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "C. C", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682829769-QTDA086012IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C The corkscrew deformity seen in diffuse esophageal spasms is characterized by abnormal esophageal contractions on the Barium swallow, and produces simultaneous segmental contractions, that obliterate the esophageal lumen to produce a ‘corkscrew esophagus’. Manometry also demonstrates these tetanic contractions. The Nutcracker esophagus is also a hypermotility disorder of the esophagus.</p>\n<p><strong>Highyeild:</strong></p><p>Corkscrew esophagus (also referred to as rosary bead esophagus) is a classic finding of diffuse esophageal spasm (DES) in barium studies reflecting abnormal contractions, leading to compartmentalization and curling of the esophagus, ultimately giving an appearance similar to a corkscrew or rosary beads.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Bird beak appearance is seen in achalasia cardia Achalasia of the cardia is a primary motor disorder of the oesophagus in which there is a failure of relaxation of the cardiac-esophageal sphincter and loss of peristalsis in the esophageal body from degeneration of myenteric plexus neurons. Dysphagia, regurgitation of undigested food, and retrosternal chest pain result, and a posteroanterior chest radiograph may show dilation of the esophagus and retention of food products as a mottled, double-contoured mediastinal widening. Barium swallow shows a classic ‘bird-beak’ appearance as a result of the failure of relaxation of the lower esophageal sphincter and an absence of peristalsis. Option B. Rat tail sign is seen in achalasia cardia Achalasia of the cardia is a primary motor disorder of the esophagus in which there is the failure of relaxation of the cardiac-esophageal sphincter and loss of peristalsis in the esophageal body from degeneration of myenteric plexus neurons. Dysphagia, regurgitation of undigested food, and retrosternal chest pain result, and a posteroanterior chest radiograph may show dilation of the esophagus and retention of food products as a mottled, double-contoured mediastinal widening. Barium swallow shows rat tail-sign. Option D. Apple core sign is seen in colorectal carcinoma due to stenosis of the colon due to carcinoma.</p>\n<p><strong>Extraedge:</strong></p><p>Apple core sign is typical of colorectal carcinoma, which produces eccentric thickening of the colon wall, leading to Obstruction.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following supply the thoracic esophagus?", "options": [{"label": "A", "text": "Inferior Thyroid Artery", "correct": false}, {"label": "B", "text": "Bronchial and esophageal branch of the thoracic aorta", "correct": true}, {"label": "C", "text": "Posterior gastric artery", "correct": false}, {"label": "D", "text": "Left gastroepiploic artery", "correct": false}], "correct_answer": "B. Bronchial and esophageal branch of the thoracic aorta", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Bronchial and esophageal branch of the thoracic aorta The thoracic esophagus is supplied by bronchial and esophageal branches of the thoracic aorta.</p>\n<p><strong>Highyeild:</strong></p><p>Arterial supply of Esophagus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. cervical esophagus - supplied by the inferior thyroid artery which is a branch of the thyrocervical trunk Option C. posterior gastric artery supplies the posterior part of the stomach Option D. left gastroepiploic artery which is a branch of the splenic artery supplies fundus of the stomach</p>\n<p><strong>Extraedge:</strong></p><p>The esophagus shares a similar structure with many of the organs in the alimentary tract: Adventitia – the outer layer of connective tissue. The very distal and intraperitoneal portion of the esophagus has an outer covering of serosa, instead of adventitia. Muscle layer – the external layer of longitudinal muscle and the inner layer of circular muscle. The external layer is composed of different muscle types in each third: Superior third –voluntary striated muscle Middle third- voluntary striated and smooth muscle Inferior third- smooth muscle Submucosa Mucosa – non-keratinized stratified squamous epithelium (contiguous with the columnar epithelium of the stomach).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following esophageal layers contain MALT?", "options": [{"label": "A", "text": "Mucosal Epithelium", "correct": false}, {"label": "B", "text": "Lamina propria", "correct": true}, {"label": "C", "text": "Muscularis mucosa", "correct": false}, {"label": "D", "text": "Sub mucosa", "correct": false}], "correct_answer": "B. Lamina propria", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lamina propria The oesophageal lamina propria contains scattered groups of mucosa-associated lymphoid tissue (MALT), especially prominent near the gastro-oesophageal junction. Small tubular mucous glands occur in this region and also at the oesophago-pharyngeal junction.</p>\n<p><strong>Highyeild:</strong></p><p>The mucosa-associated lymphoid tissue (MALT) initiates immune responses to specific antigens encountered along all mucosal surfaces . MALT inductive sites are secondary immune tissues where antigen sampling occurs and immune responses are initiated.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. mucosal epithelium contains Langerhans cells are present in the oesophageal epithelium. They are immature dendritic cells and resemble those found in the epidermis. They perform similar antigen-processing and antigen-presenting roles, which are important in the immunostimulation of naïve T cells and mucosal defense. By antigen presentation, these cells are an important part of the innate immune system Option C. Muscularis mucosae The muscularis mucosae are composed mainly of longitudinal smooth muscle and form a thin sheet near the epithelium, the contours of which it follows closely. At the pharyngeal end of the oesophagus, it may be absent or represented only by sparse, scattered bundles; below this, it becomes progressively thicker. The longitudinal orientation of its cells changes to a more plexiform arrangement near the gastro-oesophageal junction. The ducts of the esophageal glands pierce the muscularis mucosae. Option D. sub mucosa The submucosa loosely connects the mucosa and the muscularis externa, penetrating the longitudinal ridges of the esophageal It contains larger blood vessels, nerves, and mucous glands. Its elastic fibers aid the closure of the esophageal lumen after peristaltic dilation.</p>\n<p><strong>Extraedge:</strong></p><p>Mucosa-associated lymphoid tissue (MALT) is a network of lymphoid cell aggregates and tissue that is distributed in submucosal layers of the gastrointestinal, genital, respiratory, and urinary tracts, as well as in the eyes, skin, thyroid, breasts, tonsils, and salivary glands.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following plexus is the prolongation of the plexus that lie anterior to tracheal bifurcation?", "options": [{"label": "A", "text": "Left Coronary Plexus", "correct": true}, {"label": "B", "text": "Right coronary plexus", "correct": false}, {"label": "C", "text": "Atrial plexus", "correct": false}, {"label": "D", "text": "Superficial part of the cardiac plexus", "correct": false}], "correct_answer": "A. Left Coronary Plexus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left Coronary Plexus The left coronary plexus is larger than the right and is formed mainly by the prolongation of the left half of the deep part of the cardiac plexus and a few fibers from the right half. It accompanies the left coronary artery to supply the left atrium and ventricle. The deep part of the cardiac plexus lies anterior to the bifurcation of the trachea and this plays an important role in the regulation of cardiac rhythm.</p>\n<p><strong>Highyeild:</strong></p><p>Deep part of the cardiac plexus is situated in front of the bifurcation of the trachea (known as the carina), above the point of division of the pulmonary artery, and behind the aortic arch. It is formed by the cardiac nerves derived from the cervical ganglia of the sympathetic trunk, and the cardiac branches of the vagus and recurrent laryngeal nerves. Deep cardiac Plexus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Right coronary plexus The right coronary plexus is formed from both superficial and deep parts of the cardiac plexus. It accompanies the right coronary artery to supply the right atrium and ventricle. Option C. Atrial plexuses The atrial plexuses are derivatives of the right and left continuations of the cardiac plexus along the coronary arteries. Their fibers are distributed to the corresponding atria, overlapping those from the coronary plexuses. Option D. Superficial (ventral) part of the cardiac plexus The superficial(ventral) part of the cardiac plexus lies inferior to the aortic arch and anterior to the right pulmonary artery. It is formed by the cardiac branch of the left superior cervical sympathetic ganglion and the lower of the two cervical cardiac branches of the left vagus. A small cardiac ganglion is usually present in this plexus immediately below the aortic arch, to the right of the ligamentum arteriosum. This part of the cardiac plexus connects with the deep part, the right coronary plexus, and the left anterior pulmonary plexus.</p>\n<p><strong>Extraedge:</strong></p><p>The superficial part of the cardiac plexus lies beneath the arch of the aorta, in front of the right pulmonary artery. It is formed by the superior cervical cardiac branch of the left sympathetic trunk and the inferior cardiac branch of the left vagus nerve. A small ganglion, the cardiac ganglion of Wrisberg, is occasionally found connected with these nerves at their point of junction. This ganglion, when present, is situated immediately beneath the arch of the aorta, on the right side of the ligamentum arteriosum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 25 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 30-Year-old woman has been admitted due to cavernous sinus thrombosis resulting from an infection on her face. Which of the following is the most direct route for the spread of infection from the face to the cavernous sinus?", "options": [{"label": "A", "text": "Pterygoid Venous Plexus", "correct": false}, {"label": "B", "text": "Superior ophthalmic vein", "correct": true}, {"label": "C", "text": "Frontal venous plexus", "correct": false}, {"label": "D", "text": "Basilar venous plexus", "correct": false}], "correct_answer": "B. Superior ophthalmic vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior ophthalmic vein The superior ophthalmic vein drains directly into the cavernous sinus. The danger area of the face is located in the triangular region from the lateral angle of the eye to the middle of the upper lip, near the nose, and is drained by the facial vein. The facial vein communicates directly with the cavernous sinus through the superior ophthalmic vein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The pterygoid venous plexus communicates with the cavernous sinus through the inferior ophthalmic vein, but it is not directly connected to the cavernous sims. Option: C. The parietal emissary veins and frontal venous plexus do not communicate directly with the cavernous sinus. Option: D. The basilar venous plexus connects the inferior petrosal sinuses and communicates with the internal vertebral venous plexus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 35-Year-old woman is admitted to the hospital for mastoiditis. The infection can erode the thin layer of the bone between the mastoid air cells and the posterior cranial fossa and spread most commonly into which of the following venous structures?", "options": [{"label": "A", "text": "Superior Sagittal Sinus", "correct": false}, {"label": "B", "text": "Inferior sagittal sinus", "correct": false}, {"label": "C", "text": "Cavernous sinus", "correct": false}, {"label": "D", "text": "Sigmoid sinus", "correct": true}], "correct_answer": "D. Sigmoid sinus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sigmoid sinus The sigmoid venous sinus empties into the internal jugular vein and drains the cranial vault. It runs along the posterior cranial fossa near the suture between the temporal and occipital bones, just lateral to the mastoid air cells.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The superior sagittal sinus lies within the superior aspect of the longitudinal fissure between the two cerebral hemispheres. Option: B. The inferior sagittal sinus runs inferior to the superior sagittal sinus within the falx cerebri and joins the great cerebral vein (of Galen) to form the straight sinus. Option: C. The cavernous sinus is located within the middle cranial fossa and receives the ophthalmic veins, the greater petrosal sinus, and other venous vessels.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 73-year-old man visits the outpatient clinic with a complaint of progressive, painless loss of vision. Radiographic examination reveals thrombophlebitis of the cavernous sinus. Through which of the following structures must a thrombus pass to cause the symptoms of this patient?", "options": [{"label": "A", "text": "Subarachnoid Space", "correct": false}, {"label": "B", "text": "The central artery", "correct": false}, {"label": "C", "text": "The central vein of the retina", "correct": true}, {"label": "D", "text": "Optic chiasm", "correct": false}], "correct_answer": "C. The central vein of the retina", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The central vein of the retina The thrombus may pass through the central vein of the retina to reach the cavernous sinus. The patient would suffer blindness because the central vein is the only vein draining the retina, and if it is occluded, blindness will ensue.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The subarachnoid space would not be associated with the blindness experienced. Option: B. Thrombus of the central artery would not cause cavernous sinus thrombophlebitis. Option: D. The optic chiasm is a neural structure that does not transmit thrombi. The ciliary ganglion is a parasympathetic ganglion; a thrombus in the cavernous sinus would not pass through it.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 56-year-old man visits the outpatient clinic with a complaint of severe headaches and ear pain. Radiological examination reveals a tumor in the middle ear cavity, invading through the bony floor. Which of the following structures will most likely be affected?", "options": [{"label": "A", "text": "The cochlea and lateral semicircular canal", "correct": false}, {"label": "B", "text": "The internal carotid artery", "correct": false}, {"label": "C", "text": "The sigmoid venous sinus", "correct": false}, {"label": "D", "text": "The internal jugular bulb", "correct": true}], "correct_answer": "D. The internal jugular bulb", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The internal jugular bulb The sigmoid sinus collects venous blood from the transverse sinuses and empties it into a small cavity known as the jugular bulb, the inferior portion of which is located beneath the bony floor of the middle ear cavity. A paraganglioma is a tumor that may originate from paraganglia cells found in the middle ear and on the jugular bulb. Tumors that originate from the jugular bulb can grow to fill the entire bulb and may effectively block blood returning to the heart from that side of the brain. Blood flow from the brain is gradually diverted toward the opposite sigmoid sinus and jugular bulb, causing the opposite venous system to expand and accommodate increased blood flow.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The cochlea and lateral semicircular canals are located in the inner ear and are not directly affected by such a tumor. Option: B. The internal carotid artery is related to the anterior wall of the middle ear cavity and is not likely to be affected by a tumor penetrating the middle ear. Option: C. The sigmoid venous sinus collects venous blood beneath the temporal bone and follows a tortuous (S-shaped) course to the jugular foramen, where it becomes continuous with the internal jugular vein at the jugular bulb.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 14 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Histology of the given part of the body leads to which of the following speech disorder:", "options": [{"label": "A", "text": "Apraxia", "correct": false}, {"label": "B", "text": "Aphasia", "correct": false}, {"label": "C", "text": "Dysarthria", "correct": true}, {"label": "D", "text": "Verbal dyspraxia", "correct": false}], "correct_answer": "C. Dysarthria", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759755690-QTDA057001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Dysarthria The given slide is the cerebellum Cerebellum lesion causes- dysarthria Histology Of cerebellum</p>\n<p><strong>Highyeild:</strong></p><p>Dysarthria is a speech sound disorder resulting from neurological injury of the motor component of the motor–speech system and is characterized by the poor articulation of phonemes. In other words, it is a condition in which problems effectively occur with the muscles that help produce speech, often making it very difficult to pronounce words. It is unrelated to problems with understanding language.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Apraxia Apraxia is a motor disorder caused by damage to the brain (specifically the posterior parietal cortex or corpus callosum, which causes difficulty with motor planning to perform tasks or movements. The nature of the damage determines the disorder's severity, and the absence of sensory loss or paralysis helps to explain the level of difficulty. Option: B. Aphasia Global aphasia is a severe form of nonfluent aphasia, caused by damage to the left side of the brain, that affects receptive and expressive language skills (needed for both written and oral language) as well as auditory and visual comprehension. This type of aphasia often results from a large lesion of the left perisylvian cortex. The lesion is caused by an occlusion of the left middle cerebral artery and is associated with damage to Broca's area, Wernicke's area, and insular regions which are associated with aspects of language. Option: D. Verbal dyspraxia Developmental verbal dyspraxia ( DVD ), also known as childhood apraxia of speech ( CAS ) and developmental apraxia of speech ( DAS ), [1] is a condition in which an individual has problems saying sounds, syllables, and words. This is not because of muscle weakness or paralysis. The brain has problems planning to move the body parts (e.g., lips, jaw, tongue) needed for speech. The individual knows what they want to say, but their brain has difficulty coordinating the muscle movements necessary to say those words. DVD/CAS is a motor disorder, which means that the problem is located in the brain and its signals, and not in the mouth. In most cases, the cause is unknown. Possible causes include genetic syndromes and disorders. Recent research has focused on the significance of the FOXP2</p>\n<p><strong>Extraedge:</strong></p><p>There are many potential causes of dysarthria . They include toxic, metabolic, degenerative diseases, traumatic brain injury, or thrombotic or embolic stroke. Degenerative diseases include parkinsonism, amyotrophic lateral sclerosis (ALS), multiple sclerosis, Huntington's disease, Niemann-Pick disease, and Friedreich's ataxia. Toxic and metabolic conditions include Wilson's disease, hypoxic encephalopathies such as drowning, and central pontine myelinolysis. These result in lesions to key areas of the brain involved in planning, executing, or regulating motor operations in skeletal muscles (i.e. muscles of the limbs), including muscles of the head and neck (dysfunction of which characterizes dysarthria). These can result in dysfunction or failure of: the motor or somatosensory cortex of the brain, corticobulbar pathways, the cerebellum, basal nuclei (consisting of the putamen, globus pallidus, caudate nucleus, substantia nigra, etc.), brainstem (from which the cranial nerves originate), or the neuromuscular junction (in diseases such as myasthenia gravis) which block the nervous system's ability to activate motor units and effect correct range and strength of movements.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All tracts pass through the superior cerebellar peduncle, except:", "options": [{"label": "A", "text": "Tectocerebellar", "correct": false}, {"label": "B", "text": "Dentatothalamic", "correct": false}, {"label": "C", "text": "Olivo cerebellar", "correct": true}, {"label": "D", "text": "Spinocerebellar", "correct": false}], "correct_answer": "C. Olivo cerebellar", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Olivo cerebellar Olivo cerebellar tract passes through the inferior cerebellar peduncle.</p>\n<p><strong>Highyeild:</strong></p><p>The olivocerebellar tract, also known as olivocerebellar fibers , are neural fibers that originate at the olivary nucleus and pass out through the hilum and decussate with those from the opposite olive in the raphe nucleus, then as internal arcuate fibers, they pass partly through and partly around the opposite olive and enter the inferior peduncle to be distributed to the cerebellar hemisphere of the opposite side from which they arise. They terminate directly on Purkinje cells as the climbing fiber input system.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Tectocerebellar The tectocerebellar tract passes through the inferior cerebellar peduncle. Option: B. Dentatothalamic The dentatothalamic tract passes through the inferior cerebellar peduncle. Option:D. Spinocerebellar The spinocerebellar tract passes through the superior cerebellar peduncle.</p>\n<p><strong>Extraedge:</strong></p><p>The dentatothalamic tract (or dentatorubrothalamic tract) is a tract that originates in the dentate nucleus and follows the ipsilateral superior cerebellar peduncle, decussating later on and reaching the contralateral red nucleus and the contralateral thalamus. The term \"dentatorubrothalamocortical\" is sometimes used to emphasize termination in the cerebral cortex.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All the following are seen in cerebellar lesions, except:", "options": [{"label": "A", "text": "Nystagmus", "correct": false}, {"label": "B", "text": "Ataxia", "correct": false}, {"label": "C", "text": "Resting tremor", "correct": true}, {"label": "D", "text": "Hypotonia", "correct": false}], "correct_answer": "C. Resting tremor", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Resting tremor Parkinson's is the most notorious disease of the basal ganglia. Classic clinical symptoms include bradykinesia, resting tremor, postural instability, and shuffling gait.</p>\n<p><strong>Highyeild:</strong></p><p>Cerebellar Lesion Signs Ataxia Decomposition of movemen Dysarthria Dysdiadochokinesia Scanning speech Dysmetria Hypotonia Intentional tremors</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Nystagmus Option:B. Ataxia Option:D. Hypotonia Nystagmus, Ataxia, and Hypotonia are all features of cerebellar lesions.</p>\n<p><strong>Extraedge:</strong></p><p>Resting tremors are a feature of Parkinson’s disease An intention, rubral, cerebellar, or coarse tremor is defined as a rhythmic, oscillatory, and high-amplitude tremor during a directed and purposeful motor movement, worsening before reaching the target. It is due to cerebellar dysfunction.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The climbing fibers of the cerebellum are from", "options": [{"label": "A", "text": "Inferior Olivary Nucleus", "correct": true}, {"label": "B", "text": "Spinocerebellar tract", "correct": false}, {"label": "C", "text": "Tectocerebellar tract", "correct": false}, {"label": "D", "text": "Superior olivary nucleus", "correct": false}], "correct_answer": "A. Inferior Olivary Nucleus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior Olivary Nucleus Sensory Fibres of Cerebellum: The afferent connections of the cerebellum are through mossy and climbing fibers. Mossy fibers: constitute all the afferents except those of oliva cerebellar fibers. synapse with dendrites, granules, and Golgi cells by forming a A single rosette surrounded by dendrites of many cells forms the glomeruli. Climbing fibers: start from cells of the inferior olivary nucleus. These olivocerebellar fibers climb up. Each fiber gives collateral branches to synapse with deep cerebellar nuclei and make monosynaptic contacts after coiling around the non-spinous part of the dendritic tree of one Purkinje cell.</p>\n<p><strong>Highyeild:</strong></p><p>Mossy fibers originating from the lateral reticular nucleus and the pontine nuclei reach the cerebellum. In contrast with mossy fibers, climbing fibers originate solely from the inferior olive in the medulla oblongata of the brain stem.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:B. Spinocerebellar tract Option:C. Tectocerebellar tract Option:D. Superior olivary nucleus Options B,C, and D are the incorrect answer because All the afferent fibers of the cerebellum are mossy fibers except olivocerebellar (from the inferior olivary nucleus) and par olivocerebellar fibers (from accessory olivary nuclei) which are climbing fibers.</p>\n<p><strong>Extraedge:</strong></p><p>Mossy fibers are one of the major inputs to the cerebellum. There are many sources of this pathway, the largest of which is the cerebral cortex, which sends input to the cerebellum via the pontocerebellar pathway. Other contributors include the vestibular nerve and nuclei, the spinal cord, the reticular formation, and feedback from deep cerebellar nuclei. Axons enter the cerebellum via the middle and inferior cerebellar peduncles, where some branch to make contact with deep cerebellar nuclei.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Cells present in the cerebellar cortex are all, except", "options": [{"label": "A", "text": "Bipolar", "correct": true}, {"label": "B", "text": "Purkinje", "correct": false}, {"label": "C", "text": "Golgi", "correct": false}, {"label": "D", "text": "Granule", "correct": false}], "correct_answer": "A. Bipolar", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Bipolar The cerebellar cortex has five cell types and bipolar cells are not among them Bipolar neurons are found in the retina.</p>\n<p><strong>Highyeild:</strong></p><p>The cerebellar cortex contains 3 layers: Molecular layer : It consists of unmyelinated nerve fibers which are derived from the parallel fibers of axons of granule cells, axons of stellate and basket cells, sensory climbing fibers, and dendrites of Purkinje and Golgi cells. It also contains stellate and basket cells. Intermediate layer: It contains a single layer of cell bodies of Purkinje cells. Inner layer: Made up of cell bodies and dendrites of granule cells, Golgi cells.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Purkinje An intermediate layer of the cerebellum cortex contains a single layer of cell bodies of Purkinje cells. Option: C. Golgi The inner layer of the cerebellar cortex is made up of cell bodies and dendrites of granule cells, Golgi cells. Option:D. Granule The inner layer of the cerebellar cortex is made up of cell bodies and dendrites of granule cells, Golgi cells.</p>\n<p><strong>Extraedge:</strong></p><p>All the intrinsic neurons of the cerebellar cortex are inhibitory except granule cells. Such a collection of inhibitory neurons is not found anywhere else in the CNS except in the cerebellum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The marked cell inhibits which of the following:", "options": [{"label": "A", "text": "Golgi Cell", "correct": false}, {"label": "B", "text": "Basket cell", "correct": false}, {"label": "C", "text": "Vestibular cell", "correct": false}, {"label": "D", "text": "Deep cerebellar nuclei", "correct": true}], "correct_answer": "D. Deep cerebellar nuclei", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686759756943-QTDA057006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deep cerebellar nuclei Marked cell - Purkinje cell Axons from Purkinje cell inhibit the deep cerebellar nuclei</p>\n<p><strong>Highyeild:</strong></p><p>Purkinje cell : It is the characteristic cell of the It is a large cell with a flask shape. It gets stimulated by climbing fibers coming from inferior olivary nuclei. The main output of this cell is to cerebellar nuclei and is inhibitory in nature. These are the main output neurons.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Golgi Cell Option: B. Basket cell Option:C. Vestibular cell Marked cell - Purkinje cell Axons from Purkinje cell inhibit the deep cerebellar nuclei so options A,B, and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Purkinje cell, a large neuron with many branching extensions is found in the cortex of the cerebellum of the brain and plays a fundamental role in controlling motor movement. They are characterized by cell bodies that are flasklike in shape, by numerous branching dendrites, and by a single long axon. Most Purkinje cells release a neurotransmitter called GABA (gamma-aminobutyric acid), which exerts inhibitory actions on certain neurons and thereby reduces the transmission of nerve impulses. These inhibitory functions enable Purkinje cells to regulate and coordinate motor movements.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 70-year-old man came with complaints of loss of balance and swaying to the left side. On examination, he had a staggering gait and an inability to walk in a straight line. Which lobe of the cerebellum might have affected gait ataxia?", "options": [{"label": "A", "text": "Anterior", "correct": true}, {"label": "B", "text": "Middle", "correct": false}, {"label": "C", "text": "Flocculonodular", "correct": false}, {"label": "D", "text": "Superior", "correct": false}], "correct_answer": "A. Anterior", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior The anterior lobe lies on the anterior part of the superior surface. It is separated from the middle lobe by the fissure prima . Lesion of the anterior lobe causes gait ataxia. There is incoordination of the lower limbs resulting in staggering gait and inability to walk in a straight line.</p>\n<p><strong>Highyeild:</strong></p><p>Morphological and functional subdivisions of the cerebellum Components, nuclei, connections, and functions of three morphological subdivisions of the cerebellum table,tr,th,td {border:1px solid black;} Subdivisions Components Nucleus Chief connections Functions Archicerebellum (oldest part) Flocculonodular lobe + lingula Nucleus fastigii Vestibulocerebellar Maintenance of equilibrium (responsible for maintaining the position of the body in space) Paleocerebellum (in between, i.e. neither oldest nor newest) The whole of the anterior lobe except the lingula Pyramid Uvula Nucleus interpositus consisting of nucleus globosus and nucleus emboliformis Spinocerebellar Controls crude movements of the limbs Neocerebellum (most recent part) Whole of posterior lobe except the pyramid and uvula Nucleus dentatus Corticoponto-cerebellar Smooth performance of highly skilled voluntary movements of precision</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. The middle lobe is the largest of three lobes situated on both surfaces. It is limited in front by the fissure prima (on the superior surface), and by the posterolateral fissure (on the inferior surface). Option: C. The flocculonodular lobe is the smallest lobe of the cerebellum. It lies on the inferior surface, in front of the posterolateral fissure. Option: D. There is no superior lobe as such called for the cerebellum,but has a superior surface. The superior surface is slightly convex. The two hemispheres are continuous with each other on this surface.</p>\n<p><strong>Extraedge:</strong></p><p>Lobes of cerebellum The anterior lobe lies on the superior surface anterior to the fissure prima. The posterior/middle lobe lies between the fissure prima on the superior surface and the posterolateral fissure on the inferior surface. The flocculonodular lobe is the smallest of all and lies on the inferior surface in front of the posterolateral fissure.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 50 year old male had complaints of truncal ataxia which can be caused due to cerebellar vermis lesion. Uvula is a part of the vermis that corresponds to the cerebellar hemisphere____", "options": [{"label": "A", "text": "Ala", "correct": false}, {"label": "B", "text": "Tonsil", "correct": true}, {"label": "C", "text": "Flocculus", "correct": false}, {"label": "D", "text": "Biventral lobule", "correct": false}], "correct_answer": "B. Tonsil", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tonsil Uvula represents the tonsils of the cerebellar hemisphere. The uvula forms a considerable portion of the inferior vermis; it is separated on either side from the tonsil by the sulcus vallecula, at the bottom of which it is connected to the tonsil by a ridge of gray matter, indented on its surface by shallow furrows, and hence called the furrowed band.</p>\n<p><strong>Highyeild:</strong></p><p>subdivisions (lobules) of the vermis and cerebellar hemisphere table,tr,th,td {border:1px solid black;} Lobes Subdivisions of vermis Subdivisions of the cerebellar hemisphere Anterior lobe Lingula Central lobule Culmen No lateral projection Alae Quadrangular lobule Posterior lobe Declive Folium Tuber Pyramid Uvula Lobulus simplex Superior semilunar lobule Inferior semilunar lobule Biventral lobule Tonsil Flocculonodular lobe Nodule Flocculus Morphological and functional subdivisions of the cerebellum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. A wing-like prolongation (ala) on each side of the central lobule. It overlaps the lingula, from which it is separated by the precentral fissure; laterally, it extends along the upper and anterior parts of each hemisphere. Option: C. Flocculus corresponds to a nodule of vermis. The flocculus is a small lobe of the cerebellum at the posterior border of the middle cerebellar peduncle anterior to the biventer lobule. Like other parts of the cerebellum, the flocculus is involved in motor control. Option: D. Biventral lobule corresponds to pyramid of vermis. The biventer lobule is a region of the cerebellum. It is triangular in shape; its apex points backward, and is joined by the gray band to the pyramid. The lateral border is separated from the inferior semilunar lobule by the postpyramidal fissure.</p>\n<p><strong>Extraedge:</strong></p><p>Morphological subdivisions Based on phylogenetic and functional criteria the cerebellum is divided into three parts, archicerebellum, paleocer-ebellum, and neocerebellum. Archicerebellum (vestibular cerebellum) Phylogenetically it is the oldest part of the cerebellum. The fishes and lower amphibians possess only this component of the cerebellum. It consists of a flocculonodular lobe and lingula. The archicerebellum is chiefly vestibular in connections and concerned with the maintenance of equilibrium, tone, and posture of trunk muscles. Paleocerebellum (spinal cerebellum) Phylogenetically it is the next part of the cerebellum to appear in terrestrial vertebrates with the appearance of limbs, as in reptiles and birds. It consists of the anterior lobe (except lingula) and the pyramid and uvula of the inferior vermis. The paleocerebellum is chiefly spinocerebellar in connections and concerned with the tone, posture, and crude movements of the limbs. Neocerebellum (cerebral cerebellum) Phylogenetically it is the most recent part of the cerebellum to develop. It is prominent in higher mammals. It is made up of the middle lobe, the largest part of the cerebellum (except the pyramid and the uvula of the inferior vermis). The neocerebellum is chiefly corticoponto-cerebellar in connections and is concerned with the smooth performance of skilled voluntary movements.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 26 year old female presented with complaints of inability to write with the right hand and to perform other fine movements. There was intention tremor and overshoot movements . Which morphological division of cerebellum is primarily concerned with regulation of fine movements?", "options": [{"label": "A", "text": "Archicerebellum", "correct": false}, {"label": "B", "text": "Paleocerebellum", "correct": false}, {"label": "C", "text": "Neocerebellum", "correct": true}, {"label": "D", "text": "None of these", "correct": false}], "correct_answer": "C. Neocerebellum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Neocerebellum The neocerebellum is the newest part of the cerebellum to develop. It is made up of the posterior/middle lobe (the largest part of the cerebellum) except the pyramid and uvula of the inferior vermis. It is primarily concerned with the regulation of fine movements of the body.</p>\n<p><strong>Highyeild:</strong></p><p>Components, nuclei, connections and functions of three morphological subdivisions of the cerebellum Subdivisions Components Nucleus Chief connections Functions Archicerebellum (oldest part) Flocculonodular lobe + lingula Nucleus fastigii Vestibulocerebellar Maintenance of equilibrium (responsible for maintaining the position of body in space) Paleocerebellum (in between, i.e. neither oldest nor newest) Whole of anterior lobe except lingula Pyramid Uvula Nucleus interpositus consisting of nucleus globosus and nucleus emboliformis Spinocerebellar Controls crude movements of the limbs Neocerebellum (most recent part) Whole of posterior lobe except pyramid and uvula Nucleus dentatus Corticoponto-cerebellar Smooth performance of highly skilled voluntary movements of precision</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. The archicerebellum phylogenetically is the oldest part of the cerebellum to appear in evolution in aquatic vertebrates. It includes the flocculonodular lobe and the lingula. It is chiefly vestibular in its connections. It controls the axial musculature and the bilateral movements used for locomotion and maintenance of equilibrium. Option: B. The paleocerebellum is the next part of the cerebellum to appear in terrestrial vertebrates with the appearance of limbs. It is made up of the anterior lobe (except lingula), and the pyramid and uvula of the inferior vermis. Its connections are chiefly spinocerebellar. It controls the tone, posture, and crude movements of the limbs.</p>\n<p><strong>Extraedge:</strong></p><p>The cerebellum is the largest part of the hindbrain and the second largest part of the brain as a whole. It weighs about 150 g. It is located in the posterior cranial fossa underneath the tentorium cerebelli and behind the pons and medulla oblongata. It is separated from the pons and medulla by a cavity of the fourth ventricle. Its surface bears numerous fissures separating narrow folia which are mostly transverse.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 50 year old patient presented with nystagmus and intention tremors. It was diagnosed as cerebellar dysfunction. Which cerebellar peduncle carries the efferent cerebello olivary fibers?", "options": [{"label": "A", "text": "Superior", "correct": false}, {"label": "B", "text": "Middle", "correct": false}, {"label": "C", "text": "Inferior", "correct": true}, {"label": "D", "text": "Both BC", "correct": false}], "correct_answer": "C. Inferior", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior The Inferior cerebellar peduncle connects the cerebellum to the medulla. It carries efferent tracts like fastigio vestibular, cerebello olivary and fastigio reticular fibers and some afferent fibers like posterior spinocerebellar, cuneocerebellar, olivocerebellar.</p>\n<p><strong>Highyeild:</strong></p><p>Afferent and efferent tracts passing through cerebellar peduncles Peduncle Afferent tracts Efferent tracts A. Superior cerebellar peduncle (connects cerebellum to midbrain) 1. Anterior spinocerebellar 2. Tectocerebellar 1. Globorubral 2. Dentatothalamic 3. Dentato-olivary 4. Fastigioreticular B. Middle cerebellar peduncle (connects cerebellum to pons) Pontocerebellar (part of the corticopontocerebellar pathway) C. Inferior cerebellar peduncle (connects cerebellum to medulla oblongata) 1. Posterior spinocerebellar 2. Cuneocerebellar (posterior external arcuate fibres) 3. Olivocerebellar 4. Parolivocerebellar 5. Reticulocerebellar 6. Vestibulocerebellar 7. Anterior external arcuate fibers 8. Striae medullaris 9. Trigeminocerebellar 1. Fastigiovestibula 2. Cerebello-olivary 3. Fastigioreticular</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Superior cerebellar peduncle connects cerebellum to the It carries Afferent like anterior spinocerebellar, tectocerebellar and efferent like dentatothalamic, dentato olivary fibres. Option: B. Middle cerebellar peduncle connects cerebellum to the pons. It carries Afferent fibers like a pontocerebellar tract.</p>\n<p><strong>Extraedge:</strong></p><p>The cerebellum is connected to the brainstem by these three pairs of large fiber tracts called cerebellar peduncles. The three primary functions of the cerebellum are Maintenance of posture. Maintenance of muscle tone. Coordination of voluntary motor activity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 23-year-old female presented with muscular hypotonia and scanning speech. On MRI, there was a destructive lesion in cerebellar neurons. Which of the neural fibers is excitatory?", "options": [{"label": "A", "text": "Purkinje", "correct": false}, {"label": "B", "text": "Granular", "correct": true}, {"label": "C", "text": "Stellate", "correct": false}, {"label": "D", "text": "Basket", "correct": false}], "correct_answer": "B. Granular", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Granular Neurons of the cerebellum are five types of which four types, i.e. Purkinje, basket, stellate, and Golgi are inhibitory. Only the granular cells are excitatory.</p>\n<p><strong>Highyeild:</strong></p><p>Cerebellar cortex consists of three distinct layers: (a) an outer molecular layer, (b) an intermediate Purkinje cell layer, and (c) an inner granular layer. Structure of cerebellar cortex</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Purkinje cell: It is the characteristic cell of the It is a large cell with a flask shape. It gets stimulated by climbing fibers coming from the inferior olivary nucleus. The main output of this cell is to cerebellar nuclei and is inhibitory in nature. These are the main output neurons. Option: C, D. Stellate cell and basket cell: Their cell bodies are at right angles to the long axis of the folium. Neurons of the cerebellum are five types of which four types, i.e. Purkinje, basket, stellate, and Golgi are inhibitory. Only the granular cells are excitatory. Therefore Option A,C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The outgoing Purkinje axons constitute the sole output from the cerebellar cortex and exert an inhibitory influence on the intracerebellar nuclei.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 50 year old female presented with complaints of swaying to the left while walking and inability to do her daily work. Her blood pressure is 140/90 mmHg. The olivocerebellar fibers are damaged. The afferents from the inferior olivary nucleus to the cerebellum are called____", "options": [{"label": "A", "text": "Mossy Fibers", "correct": false}, {"label": "B", "text": "Climbing fibers", "correct": true}, {"label": "C", "text": "Axon of purkinje", "correct": false}, {"label": "D", "text": "Axon of granular", "correct": false}], "correct_answer": "B. Climbing fibers", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Climbing fibers Climbing fibers start from cells of the inferior olivary nucleus. These olivocerebellar fibers climb up. Each fiber gives collateral branches to synapse with deep cerebellar nuclei and make monosynaptic contacts after coiling around the non-spinous part of the dendritic tree of one Purkinje cell. These fibers release neurotransmitters aspartate.</p>\n<p><strong>Highyeild:</strong></p><p>Mossy fibers originating from the lateral reticular nucleus and the pontine nuclei reach the cerebellum. In contrast with mossy fibers, climbing fibers originate solely from the inferior olive in the medulla oblongata of the brain stem. Cerebellar cortex</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Mossy fibers constitute all the afferents except those of olivocerebellar fibers. Mossy fibres synapse with dendrites, granules, and Golgi cells by forming a rosette. A single rosettle surrounded by dendrites of many cells forms the glomeruli. These fibers release neurotransmitter and glutamate. Option: C. The main output of axon of purkinje cell is to cerebellar nuclei and is inhibitory in nature. These are the main output neurons. Option: D. The axons of granular cells form parallel fibres which are connected to other cells.</p>\n<p><strong>Extraedge:</strong></p><p>Purkinje cell, a large neuron with many branching extensions that is found in the cortex of the cerebellum of the brain and that plays a fundamental role in controlling motor movement. They are characterized by cell bodies that are flasklike in shape, by numerous branching dendrites, and by a single long axon. Most Purkinje cells release a neurotransmitter called GABA (gamma-aminobutyric acid), which exerts inhibitory actions on certain neurons and thereby reduces the transmission of nerve impulses. These inhibitory functions enable Purkinje cells to regulate and coordinate motor movements.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 62 year old male presented with patchy memory loss. He showed a lack of attention and there were grammatical errors in his speech. Intention tremors and nystagmus are also found. On an angiogram, he had an ischemic stroke of one of the cerebellar arteries. Which cerebellar artery is a branch of the vertebral artery?", "options": [{"label": "A", "text": "Superior Cerebellar", "correct": false}, {"label": "B", "text": "Anterior inferior cerebellar", "correct": false}, {"label": "C", "text": "Posterior inferior cerebellar", "correct": true}, {"label": "D", "text": "AC", "correct": false}], "correct_answer": "C. Posterior inferior cerebellar", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior inferior cerebellar Posterior inferior cerebellar is a branch of the vertebral artery. It is one of the three main arteries that supply blood to the cerebellum, a part of the brain. Blockage of the posterior inferior cerebellar artery can result in a type of stroke called lateral medullary syndrome.</p>\n<p><strong>Highyeild:</strong></p><p>The posterior inferior cerebellar artery (PICA ) is the largest branch of the vertebral artery. It is one of the three main arteries that supply blood to the cerebellum, a part of the brain. Blockage of the posterior inferior cerebellar artery can result in a type of stroke called lateral medullary syndrome. Circle of Willis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Superior cerebellar artery is a branch of the basilar artery. The superior cerebellar artery supplies most of the cerebellar cortex, the cerebellar nuclei, and the superior cerebellar peduncle. Option: B. Anterior inferior cerebellar is a branch of the basilar artery. The anterior inferior cerebellar artery supplies the middle cerebellar peduncle, lower lateral pons, anteroinferior surface of the cerebellum, flocculus, and choroid plexus of the lateral ventricle.</p>\n<p><strong>Extraedge:</strong></p><p>A disrupted blood supply to posterior inferior cerebellar arteries due to a thrombus or embolus can result in a stroke and lead to the lateral medullary syndrome. Severe occlusion of this artery or vertebral arteries could lead to Horner's Syndrome as well.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 23 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 70-year-old male, with a history of atrial fibrillation presented with horizontal diplopia. Neurologic examination revealed that the two eyes deviate to the right side and the inability to turn left. The involuntary tracking movements are unaffected. MRI brain showed lesions on certain functional areas in the brain. Which area might have been affected?", "options": [{"label": "A", "text": "Primary Visual Area", "correct": false}, {"label": "B", "text": "Frontal eye field", "correct": true}, {"label": "C", "text": "Prefrontal area", "correct": false}, {"label": "D", "text": "Secondary visual area", "correct": false}], "correct_answer": "B. Frontal eye field", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Frontal eye field Frontal Eye Field (Area 8 of Brodmann) : The frontal eye field controls voluntary scanning movements of the eyes and is independent of the visual stimuli. The frontal eye field is connected to the visual area of the occipital cortex by association fibers. Lesions of the frontal eye field of one hemisphere cause the two eyes to deviate to the side of the lesion and an inability to turn the eyes to the opposite side. The involuntary tracking movement of the eyes when following moving objects is unaffected since the lesion does not involve the visual cortex of the occipital lobe.</p>\n<p><strong>Highyeild:</strong></p><p>The Frontal Eye Field area is responsible for saccadic eye movements for the purpose of visual field perception and awareness, as well as for voluntary eye movement. The FEF communicates with extraocular muscles indirectly via the paramedian pontine reticular formation. Destruction of the FEF causes deviation of the eyes to the ipsilateral side.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option: A. The involuntary following of moving objects by the eyes involves the visual area of the occipital cortex. The primary visual area is situated in the walls and floor of the posterior part of the calcarine sulcus (post calcarine sulcus) and may extend around the occipital pole onto the supero lateral surface of the hemisphere. Option: C. The part of the frontal lobe rostral to the motor and premotor areas is referred to as the prefrontal area. Bilateral destruction of prefrontal areas due to trauma or tumours results in profound changes in personality. There is a loss of concentration, initiative, and judgment. Option: D. The secondary visual area surrounds the primary visual area and occupies most of the remaining visual cortex on the medial and superolateral surfaces of the cerebral hemisphere. Lesions of the secondary visual area result in a loss of ability to recognize objects (visual agnosia) seen in the opposite field of vision.</p>\n<p><strong>Extraedge:</strong></p><p>Supplementary eye field ( SEF ) is the name for the anatomical area of the dorsal medial frontal lobe of the primate cerebral cortex that is indirectly involved in the control of saccadic eye movements.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 58 year old female with complaints of a history of repetitiveness, memory loss, and executive function loss for 2 years. MRI scan revealed mild generalized cortical atrophy in the koniocortex. Which group of cells are included in the koniocortex?", "options": [{"label": "A", "text": "Pyramidal Cells", "correct": false}, {"label": "B", "text": "Stellate cells", "correct": true}, {"label": "C", "text": "Cells of Martinotti", "correct": false}, {"label": "D", "text": "Horizontal cells of Cajal", "correct": false}], "correct_answer": "B. Stellate cells", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Stellate cells The stellate/granule cells are much smaller than pyramidal cells and their cell bodies measure about 8 µm in diameter. They have star-shaped bodies with short axons and many dendrites. These cells are so small that they appear like granules in Nissl-stained material, hence the name, granule cells. In certain areas of the cerebral cortex, they are so numerous that they resemble a cloud of dust particles, and the cerebral cortex in these areas is called koniocortex .</p>\n<p><strong>Highyeild:</strong></p><p>In the neocortex, the layers are numbered from superficial (I) to deep (VI), The layers are: molecular layer external granular layer external pyramidal layer internal granular layer internal pyramidal layer multiform layer</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The pyramidal cells are pyramidal in shape with their apices directed towards the surface. The axon arises from the base of the cell body while dendrites arise from its apex and basal angles. The axons enter the white matter as projection fibers. Option: C. The cells of Martinotti are small multipolar cells that are present throughout the layers of the cerebral cortex. Option: D. The horizontal cells of Cajal are fusiform and oriented horizontally. They are found in the most superficial layer of the cortex.</p>\n<p><strong>Extraedge:</strong></p><p>The neuronal cells of the cortex consist of six main cell types. These are the pyramidal cells (the main output neurons of the cerebral cortex), fusiform cells, stellate (granular) cells, basket cells, horizontal cells of Cajal-Retzius, and cells of Martinotti.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 62-year-old man presented with behavior and personality changes associated with progressive difficulty in recognizing familiar faces, such as those of co-workers and famous people. He did not have any weakness, parkinsonism, bulbar symptoms, or alien limb phenomenon. MRI showed marked right temporal anterior atrophy. The neuropsychological assessment showed frontal lobe dysfunction, verbal perseverance, and mild memory impairment but visual and space perceptions were normal. It was diagnosed as frontotemporal dementia affecting the External band of Baillarger. Which layer of the cerebral cortex contains the external band of Baillarger?", "options": [{"label": "A", "text": "External Pyramidal Layer", "correct": false}, {"label": "B", "text": "Internal pyramidal layer", "correct": false}, {"label": "C", "text": "Internal granular layer", "correct": true}, {"label": "D", "text": "Multiform layer", "correct": false}], "correct_answer": "C. Internal granular layer", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Internal granular layer Internal granular layer is made up of closely packed stellate (granule) cells. In the middle of this layer, there is a band of horizontally arranged white fibers called white stria or external bands of Baillarger. The white stria is most marked in the visual cortex, hence also called the striate cortex.</p>\n<p><strong>Highyeild:</strong></p><p>Layers of Neocortex Layer I Layer I is the molecular layer and contains a few scattered neurons, including GABAergic rosehip neurons. Layer I consists largely of extensions of apical dendritic tufts of pyramidal neurons and horizontally oriented axons, as well as glial cells. Layer II Layer II, the external granular layer, contains small pyramidal neurons and numerous stellate neurons. Layer III Layer III, the external pyramidal layer , contains predominantly small and medium-sized pyramidal neurons, as well as non-pyramidal neurons with vertically oriented intracortical axons; layers I through III are the main target of interhemispheric corticocortical afferents, and layer III is the principal source of corticocortical afferents. Layer IV Layer IV, the internal granular layer, contains different types of stellate and pyramidal cells. The layers above layer IV are also referred to as supragranular layers (layers I-III), whereas the layers below are referred to as infragranular layers (layers V and VI). Layer V Layer V, the internal pyramidal layer , contains large pyramidal neurons. Axons from these leave the cortex and connect with subcortical structures including the basal ganglia. In the primary motor cortex of the frontal lobe, layer V contains giant pyramidal cells called Betz cells, whose axons travel through the internal capsule, the brain stem, and the spinal cord forming the corticospinal tract, which is the main pathway for voluntary motor control. Layer VI Layer VI, the polymorphic or multiform layer, contains few large pyramidal neurons and many small spindle-like pyramidals and multiform neurons; layer VI sends efferent fibers to the thalamus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. External pyramidal layer is made up of small and medium-sized pyramidal cells. The sizes of cells increase from superficial to deeper borders of the layer. Option: B. Internal pyramidal (ganglionic) layer is made up mainly of large pyramidal cells (of Betz). The basal part of this layer contains a thin band of horizontally arranged fibers called the inner band of Baillarger. These cells account for about 3% of the projection fibers of the corticospinal (pyramidal) tract. Option: D. Multiform layer (or layer of polymorphic cells) is made up of cells of multiple forms (i.e. neurons of various sizes and shapes). This layer fuses with the white matter.</p>\n<p><strong>Extraedge:</strong></p><p>The neocortex is formed of six layers, numbered I to VI, from the outermost layer I – near the pia mater, to the innermost layer VI – near the underlying white matter. Each cortical layer has a characteristic distribution of different neurons and their connections with other cortical and subcortical regions. There are direct connections between different cortical areas and indirect connections via the thalamus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old male presented to OPD with complaints of difficulty in communication. He says that even though he could think or write of the words he wishes to say he couldn't express them in words. On examination, blood pressure was 150/90 mmHg, the output of spontaneous speech is markedly diminished, and loss of normal grammatical structure but good comprehension. Where is the lesion located?", "options": [{"label": "A", "text": "Wernicke Area", "correct": false}, {"label": "B", "text": "Broca area", "correct": true}, {"label": "C", "text": "Premotor area", "correct": false}, {"label": "D", "text": "Primary motor area", "correct": false}], "correct_answer": "B. Broca area", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Broca area Motor speech area of Broca occupies the opercular and triangular portions of the inferior frontal gyrus corresponding to the areas 44 and 45 of Brodmann. Lesion of Broca’s area on the dominant side of the hemisphere causes expressive aphasia. It is characterized by hesitant and distorted speech with relatively good comprehension. It results in loss of ability to produce speech, i.e. expressive aphasia (also called motor aphasia). The patients, however, retain the ability to think about the words they wish to say, they can write the words, and they can understand their meaning when they see or hear them. Thus, although the language is understood, it cannot be expressed in speech even though there is no paralysis of the muscles of the lips, tongue, and vocal cords. Motor speech area of brain</p>\n<p><strong>Highyeild:</strong></p><p>Aphasia common patient presentation . Comprehension Repetition of Spoken Language Naming Fluency Wernicke's Impaired Impaired Impaired Preserved or increased Broca's Preserved (except grammar) Impaired Impaired Decreased Global Impaired Impaired Impaired Decreased Conduction Preserved Impaired Impaired Preserved Nonfluent (motor) transcortical Preserved Preserved Impaired Impaired Fluent (sensory) transcortical Impaired Preserved Impaired Preserved Isolation Impaired Echolalia Impaired No purposeful speech Anomic Preserved Preserved Impaired Preserved except for word-finding pauses Pure word deafness Impaired only for spoken language Impaired Preserved Preserved Pure alexia Impaired only for reading Preserved Preserved Preserved</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Receptive Speech Area of Wernicke is also known as sensory language area. Lesions of Wernicke's area in the dominant hemisphere produce a loss of ability to understand spoken and written speech. This condition is called receptive sensory aphasia. Since Broca's area is unaffected, expressive speech is unimpaired and the individual can produce fluent speech. However, he is unaware of the meaning of the words he uses consequently he uses, incorrect words or even non-existent words. Option: C. Premotor area coincides with Brodmann's area 6 and is situated anterior to the motor area in the superolateral and medial surfaces of the hemisphere. Lesion of supplementary motor area 6 leads to apraxia and akinesia. This is the condition that involves difficulty in performing the skilled movements once learned, in the absence of paralysis, ataxia, or sensory loss. When the disability affects writing, it is called agraphia. Option: D. Destructive lesion of primary motor area 4 results in voluntary paresis of the affected part of the Spastic voluntary paralysis of the opposite side of the body characteristically follows, if the lesion spreads beyond area 4 or that interrupts projection fibers in the medullary center or internal capsule. Irritative lesion of the motor area leads to focal convulsive movements of the corresponding part of the body, referred to as Jacksonian epilepsy.</p>\n<p><strong>Extraedge:</strong></p><p>Wernicke's area , also called Wernicke's speech area , is one of the two parts of the cerebral cortex that are linked to speech, the other being Broca's area. It is involved in the comprehension of written and spoken language, in contrast to Broca's area, which is primarily involved in the production of language. It is traditionally thought to reside in Brodmann area 22, which is located in the superior temporal gyrus in the dominant cerebral hemisphere, which is the left hemisphere in about 95% of right-handed individuals and 70% of left-handed individuals. Damage caused to Wernicke's area results in receptive, fluent aphasia. This means that the person with aphasia will be able to fluently connect words, but the phrases will lack meaning. This is unlike non-fluent aphasia, in which the person will use meaningful words, but in a non-fluent, telegraphic manner.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 59 year old male was admitted with complaints of paralysis of the extremities of the right half of the body. On examination, blood pressure was 180/70 mmHg. There is a motor cortex lesion. The voluntary smile of the patient accentuated the asymmetry and not the genuine smile. What might be the reason?", "options": [{"label": "A", "text": "Voluntary smile uses extrapyramidal pathway only", "correct": false}, {"label": "B", "text": "Genuine smile uses extrapyramidal pathway only", "correct": true}, {"label": "C", "text": "Voluntary smile uses pyramidal pathway only", "correct": false}, {"label": "D", "text": "Genuine smile uses pyramidal pathway only", "correct": false}], "correct_answer": "B. Genuine smile uses extrapyramidal pathway only", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Genuine smile uses extrapyramidal pathway only Voluntary smile in a stroke patient will accentuate the asymmetry. A genuine smile that uses only extrapyramidal pathways will be symmetrical and there will be no asymmetry for the duration of the smile. # High Yield</p>\n<p><strong>Highyeild:</strong></p><p>A voluntary smile (pyramidal smile ) mediated by corticobulbar circuits was different from our patient's emotional smile . A genuine smile that uses only extrapyramidal pathways will be symmetrical and there will be no asymmetry for the duration of the smile.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options A, C & D: - Voluntary smile in a stroke patient will accentuate the asymmetry. The motor cortex is required only for voluntary movement. Destructive lesion of primary motor area 4 results in voluntary paresis of the affected part of the Spastic voluntary paralysis of the opposite side of the body characteristically follows, if the lesion spreads beyond area 4 or that interrupts projection fibers in the medullary center or internal capsule.</p>\n<p><strong>Extraedge:</strong></p><p>The part of your brain responsible for smiling is housed in the cingulate cortex, which is an unconscious response area. This part of the brain is responsible for controlling smiles both when you are happy and mimicking the expressions of others.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 52 year old man suffered from a gunshot wound on the right side of the occiput and was brought to the emergency department. On examination, there was loss of vision in the left visual field and loss of peripheral vision with normal macular sparing. What might the lesion in the primary visual area?", "options": [{"label": "A", "text": "Bitemporal Hemianopia", "correct": false}, {"label": "B", "text": "Left nasal hemianopia", "correct": false}, {"label": "C", "text": "Right homonymous hemianopia", "correct": true}, {"label": "D", "text": "Right superior quadrantanopia", "correct": false}], "correct_answer": "C. Right homonymous hemianopia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right homonymous hemianopia Primary visual area 17 : Lesion of this area, leads to loss of vision in the visual field of the opposite side-homonymous hemianopia. The unilateral lesions of the superior wall of post calcarine sulcus result in inferior quadrantic hemianopia, whereas lesions involving the inferior wall of post calcarine sulcus result in superior quadrantic hemianopia. The most common causes of these lesions are vascular accidents, tumors, and injuries from gunshot wounds. A common finding with most of the lesions of the occipital cortex is loss of peripheral vision with normal macular vision, called macular sparing.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Bitemporal hemianopia: Optic chiasma lesion, if central will lead to bitemporal hemianopia, but if peripheral on both sides will lead to binasal hemianopia. Option: B. chiasma lesion at the left side and at the periphery causes Left nasal hemianopia. Option: D. Homonymous superior quadrantanopia, also called \"pie in the sky\" is caused by damage to the contralateral inferior parts of the posterior visual pathway: the inferior optic radiation, or the inferior part of the occipital visual cortex below the calcarine fissure.</p>\n<p><strong>Extraedge:</strong></p><p>Homonymous hemianopsia can be congenital, but is usually caused by brain injury such as from stroke, trauma, tumors, infection, or following surgery. Vascular and neoplastic (malignant or benign tumors) lesions from the optic tract to the visual cortex can cause a contralateral homonymous hemianopia. Injury to the right side of the brain will affect the left visual fields of each eye.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 54 year old man who was diagnosed with stroke had the inability to identify objects by feeling. On examination, the blood pressure was 180/70 mmHg. Which cortical area is associated with stereognosis?", "options": [{"label": "A", "text": "Primary Sensory Area(3,1,2)", "correct": false}, {"label": "B", "text": "Secondary sensory area", "correct": false}, {"label": "C", "text": "Sensory association area(5,7)", "correct": true}, {"label": "D", "text": "Wernicke's speech area", "correct": false}], "correct_answer": "C. Sensory association area(5,7)", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sensory association area(5,7) Sensory association area occupies the superior parietal lobule corresponding to Areas 5 and 7 of Brodmann. It is concerned with the perception of the shape, size, roughness, and texture of the objects. Thus, it enables the individual to recognize the objects placed in his/her hand without seeing. Such ability is referred to as stereognosis. Lesions of sensory association area result in an inability to recognize or identify an object by its feel. This condition is called tactile agnosia or astereognosis. Secondary sensory area (SmII)</p>\n<p><strong>Highyeild:</strong></p><p>Secondary sensory area is located in the upper lip of the posterior ramus of the lateral sulcus. The face area lies most anterior and the leg area is posterior. The whole body is represented bilaterally. This area relates more to pain perception. The ablation of this area may relieve intractable pain. Sensory association area(5,7)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Lesions of the primary sensory area lead to the loss of appreciation of exteroceptive and proprioceptive sensations from the opposite half of the body. The crude pain, temperature, and touch sensations often return, but this is believed to be due to functions of the thalamus. Option: B. Secondary sensory area is located in the upper lip of the posterior ramus of the lateral The face area lies most anterior and the leg area is posterior. The whole body is represented bilaterally. This area relates more to pain perception. Option; D. Lesions of Wernicke's area in the dominant hemisphere produce a loss of ability to understand spoken and written speech. This condition is called receptive sensory aphasia. Since Broca's area is unaffected, the expressive speech is unimpaired and the individual can produce fluent speech However, he is unaware of the meaning of the words he spoke. Primary sensory area (areas 3, 1, and 2 of Brodmann)</p>\n<p><strong>Extraedge:</strong></p><p>Primary sensory area (areas 3, 1, and 2 of Brodmann) this line not in extraedge kindly add Primary sensory area is located in the postcentral gyrus and extends into the posterior part of the paracentral lobule on the medial surface of the hemisphere. The opposite half of the body is represented upside down exactly in the same fashion as in the primary motor area. Similarly, the area of the cortex assigned for a particular part is not proportional to the size of that part but to its functional significance (i.e. to the intricacies of sensations received from it). Thus, the thumb, fingers, lips, and tongue have a disproportionately large representation. The primary sensory area is concerned with the perception of exteroceptive (pain, touch, and temperature) and proprioceptive (vibration, muscle, and joint sense) sensations from the opposite half of the body. However, sensations from the pharynx, larynx, and perineum go to both sides.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 40 year old male presented with complaints of weakness of the right limb, spasticity, and hyperreflexia. Babinski sign was able to elicit. On an MRI scan, there was a lesion in the pyramidal tract. Which among the following is true about a pyramidal cell?", "options": [{"label": "A", "text": "Afferent In Connection", "correct": false}, {"label": "B", "text": "More pronounced in motor cortex", "correct": true}, {"label": "C", "text": "Seen in a fusiform layer of cortex", "correct": false}, {"label": "D", "text": "They are Golgi type 2 cells", "correct": false}], "correct_answer": "B. More pronounced in motor cortex", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>More pronounced in motor cortex The pyramidal cells are more pronounced in the motor areas , whereas the granular cells are more conspicuous in the sensory areas of the brain. In between the nerve cells are the nerve fibers of these cells and capillaries. The pyramidal or corticospinal tract is formed by the axons of pyramidal cells predominantly lying in the motor area of the cerebral cortex.</p>\n<p><strong>Highyeild:</strong></p><p>Layers of the Cerebral Cortex - The neocortex consists of six layers or laminae. From superficial to deep these are as follows: Molecular (plexiform) layer is made up predominantly of nerve fibers and a few scattered horizontal cells of Cajal. External granular layer is made up mainly of densely packed stellate (granule) cells. External pyramidal layer is made up of small and medium-sized pyramidal cells. The sizes of cells increase from superficial to deeper borders of the layer. Internal granular layer is made up of closely packed stellate (granule) cells. In the middle of this layer, there is a band of horizontally arranged white fibers called white stria or external bands of Baillarger. The white stria is most marked in the visual cortex, hence the visual cortex is also called the striate cortex. Internal pyramidal (ganglionic) layer is made up mainly of large pyramidal cells (of Betz). The basal part of this layer contains a thin band of horizontally arranged fibers called the inner band of Baillarger. These cells account for about 3% of the projection fibers of the corticospinal (pyramidal) tract. Multiform layer (or layer of polymorphic cells) is made up of cells of multiple forms (i.e. neurons of various sizes and shapes). This layer fuses with the white matter. Six Layers of the Cerebral Cortex</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The granular cell layers are afferent in connection and the pyramidal cell layers are efferent in nature. Afferent nerve fibers are the axons carried by a sensory nerve that relays sensory information from sensory receptors to regions of the brain. The efferent fiber is a long process projecting far from the neuron's body that carries nerve impulses away from the central nervous system toward the peripheral effector organs Option: C. Fusiform layer or polymorphous layer contains mainly fusiform cells with a few stellate cells. No pyramidal cells are seen in this layer. Fusiform cells are usually placed in the deepest cortical layer. Their dendrite projects towards the cortical surface, whereas the axon also has the possibility to be commissural, association or projection oriented. Option: D. Pyramidal cells are Golgi type 1 neurons. These neurons have long axons and numerous short dendrites. These are seen in pyramidal cells of the cerebral cortex, Purkinje cells of the cerebellum, and anterior horn cells of the spinal cord. Golgi Type II are neurons with short axons and establish synapses with neighboring neurons. These Golgi type II neurons have a star-like appearance and are found in cerebral and cerebellar cortices and retina.</p>\n<p><strong>Extraedge:</strong></p><p>Granular cortex: In this type, the granular layers are well developed while the pyramidal layers are poorly developed. Since the density of granule cells is very high, it is termed granular cortex. The granular cortex is the characteristic feature of the sensory areas, viz. primary sensory, acoustic, and visual areas. Agranular cortex : In this type, the granular layers are poorly developed while pyramidal layers are well developed with densely packed pyramidal cells. The agranular cortex is the characteristic feature of the motor areas, viz. primary motor and other areas of the frontal lobe. The cortex is named agranular due to the paucity or absence of granule cells.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A male patient of 25 years old was brought with complaints of difficulty in understanding spoken words, in identification and categorization of objects, difficulty in learning, disturbance with elective attention to what he sees or hears, and verbal memory is impaired. Which lobe of the cerebrum must have been affected here?", "options": [{"label": "A", "text": "Temporal Lobe- Dominant", "correct": true}, {"label": "B", "text": "Temporal lobe- non dominant", "correct": false}, {"label": "C", "text": "Parietal lobe- dominant", "correct": false}, {"label": "D", "text": "Parietal lobe- non dominant", "correct": false}], "correct_answer": "A. Temporal Lobe- Dominant", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Temporal Lobe- Dominant The main functions of the temporal lobe (dominant)are language, verbal memory, and auditory perception. The damage to the temporal dominant lobe is presented as dyslexia, verbal memory impaired, and receptive aphasia. Receptive aphasia is the difficulty in understanding spoken words.</p>\n<p><strong>Highyeild:</strong></p><p>Main Functions of different lobes of cerebrum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. The main functions of the temporal nondominant lobe are auditory perception, pitch perception, non-verbal memory, smell, and balance. Its damage causes reception aphasia and impaired musical skills. Option: C. The functions of the parietal lobe(dominant) are language, calculation, analytical, logical, and geometrical. Its damage cause dyscalculia, dyslexia, apraxia (inability to do complex movements), and agnosia (inability to recognize). Option: D. Parietal lobe(nondominant) functions are spatial orientation, recognition of faces, and appreciation of music and figures. Its damage cause spatial disorientation, non-recognition of faces.</p>\n<p><strong>Extraedge:</strong></p><p>Supplementary motor area (MsII) Supplementary motor area is located in the medial frontal gyrus on the medial surface of the hemisphere anterior to the paracentral lobule. The body is represented from before backward in craniocaudal order. The stimulation of the supplementary motor area produces complex movements, some are described as ‘assumption of posture’ with bilateral effects, including turning the head, assuming positions of the trunk and lower limb, etc.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 28 year old male presented with complaints of loss of mobility and control on the left side of the body (the patient is left-handed). He also had trouble with attention, perception, and memory. His blood pressure was 140/90 mmHg.He had a past history of cerebrovascular accident 3 years back. On an MRI scan, it was diagnosed as right hemisphere brain damage. The right hemisphere controls all except", "options": [{"label": "A", "text": "Artistic", "correct": false}, {"label": "B", "text": "Religious", "correct": false}, {"label": "C", "text": "Mathematical", "correct": true}, {"label": "D", "text": "Imaginative", "correct": false}], "correct_answer": "C. Mathematical", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Mathematical The right hemisphere is active in understanding geometrical figures, imaginative, artistic, religious, and important for temporal synthesis and spatial comprehension. It helps in the recognition of faces, figures, and appreciating music. The left hemisphere is verbal, mathematical, analytical, scientific, and calculative and has direct link to consciousness. One cerebral hemisphere dominates the other one in relation to handedness, speech, perception of language, and spatial judgment. In 80-95% of subjects, the left hemisphere dominates the right one. The dominant lobe contains the Broca's motor speech area. Since the left hemisphere controls the right half of the body, all these subjects are right-handed.</p>\n<p><strong>Highyeild:</strong></p><p>The left hemisphere is more efficient as far as handedness, perception of language, speech, writing, and calculation (numerical skills) are concerned. The right hemisphere is more efficient with spatial perception (geometrical and spatial relationships), recognition of faces, creative acts of arts and music, and non-verbal ideation.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option:A. Artistic Option:B. Religious Option:D. Imaginative The right hemisphere is active in understanding geometrical figures, imaginative, artistic, religious, and important for temporal synthesis and spatial comprehension. It helps in the recognition of faces, figures, and appreciation of Therefore Options A, B, and D are all controlled by the right cerebral hemisphere, so Options A, B, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The term dominant hemisphere refers to the side concerned with the perception and production of language/ speech. According to this concept, the left hemisphere is dominant in over 90% of people, in whom the right hemisphere is described as the minor or non-dominant hemisphere . The left hemisphere controls the right side of the body, including the skillful right hand. Consequently, over 90% of the adult population is right-handed. During childhood, one hemisphere slowly comes to dominate over the other, and it is only after the first decade that the dominance becomes fixed.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 52 year old woman who is a known case of hypertension was brought to ED with complaints of weakness of the right side, dizziness, numbness, speech difficulty, and visual disturbances. On examination, blood pressure was 180/90 mmHg. MRI scan was done and diagnosed as an ischemic stroke of an artery that supplies a major superolateral part of cerebral hemispheres. Which is that artery?", "options": [{"label": "A", "text": "Anterior Cerebral Artery", "correct": false}, {"label": "B", "text": "Middle cerebral artery", "correct": true}, {"label": "C", "text": "Posterior cerebral artery", "correct": false}, {"label": "D", "text": "Anterior choroidal artery", "correct": false}], "correct_answer": "B. Middle cerebral artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Middle cerebral artery Superolateral surface is mostly supplied by the middle cerebral artery , the largest and direct branch of the internal carotid artery. It lies in the lateral sulcus and on the insula. Small portions of the superolateral surface are also supplied by the anterior cerebral artery and posterior cerebral artery.</p>\n<p><strong>Highyeild:</strong></p><p>Branches of the main arteries of the brain Cerebral part of internal carotid artery Fourth part of vertebral artery Basilar artery Ophthalmic artery Meningeal arteries Anterior inferior cerebellar artery Anterior cerebral artery Anterior spinal artery Labyrinthine artery Middle cerebral artery Posterior spinal artery Pontine arteries Posterior communicating artery Posterior inferior cerebellar artery Superior cerebellar artery Anterior choroidal artery Medullary arteries Posterior cerebral artery</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Anterior cerebral artery is the smaller terminal branch of Internal carotid artery. It supplies the major part of the medial surface of the cerebral hemisphere. The two arteries are connected by the anterior communicating artery. Option: C. Posterior cerebral artery is the terminal branch of the basilar artery. It winds around the cerebral peduncle to reach the tentorial surface. It supplies the majority of the inferior part of the cerebral hemispheres. Option: D. The anterior choroidal is a branch of the internal carotid artery. It supplies blood to the choroid plexus of the inferior horn of the lateral ventricle.</p>\n<p><strong>Extraedge:</strong></p><p>Arterial supply of the superolateral (A), medial (B), and inferior (C) surfaces of the cerebral hemisphere.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 20 year old man was brought to ED with a road traffic accident and severe head injury. His blood pressure was 80/50mmHg. Saline infusion and blood transfusion were done. He had poor localization of stimulus and loss of discriminative sensations of fine touch and position. On a CT scan, there was a destructive lesion on the sensory area of the brain. The sensory area of the cortex has a representation of body parts arranged upside down. Which of them has the largest representation?", "options": [{"label": "A", "text": "Thumb", "correct": false}, {"label": "B", "text": "lips", "correct": false}, {"label": "C", "text": "Tongue", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above Primary sensory area (areas 3, 1, and 2 of Brodmann) Primary sensory area is located in the postcentral gyrus and extends into the posterior part of the paracentral lobule on the medial surface of the hemisphere. The opposite half of the body is represented up-side down exactly in the same fashion as in the primary motor area. Similarly, the area of the cortex assigned for a particular part is not proportional to the size of that part but to its functional significance (i.e. to the intricacies of sensations received from it). Thus, the thumb, fingers, lips, and tongue have a disproportionately large representation. The primary sensory area is concerned with the perception of exteroceptive (pain, touch, and temperature) and proprioceptive (vibration, muscle, and joint sense) sensations from the opposite half of the body. However, sensations from the pharynx, larynx, and perineum go to both sides.</p>\n<p><strong>Highyeild:</strong></p><p>Primary motor area The human body is represented in an upside-down manner in the precentral gyrus (inverted homunculus) as shown in the image below. The pharyngeal region and tongue are represented in the lowermost part, followed by the face, hand, trunk, and thigh. The legs, feet, and perineum are represented on the medial surface of the hemisphere in the paracentral lobule. The motor (A) and sensory (B) homunculi show proportional somatotopic representation in the main motor and sensory cortex</p>\n<p><strong>Extraedge:</strong></p><p>Lesions of the primary sensory area lead to the loss of appreciation of exteroceptive and proprioceptive sensations from the opposite half of the body. The crude pain, temperature, and touch sensations often return, but this is believed to be due to functions of the thalamus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 26 year old female presented with a history of traumatic brain injury. On examination, she had a defect in understanding tactile information and was unable to recognize objects held in hand with her eyes closed. It was diagnosed as a lesion on the superior parietal lobule. Which is the Broadman's area affected?", "options": [{"label": "A", "text": "5,7", "correct": true}, {"label": "B", "text": "3,1,2", "correct": false}, {"label": "C", "text": "44,45", "correct": false}, {"label": "D", "text": "40", "correct": false}], "correct_answer": "A. 5,7", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>5,7 Somesthetic association cortex (superior parietal lobule) areas 5 and 7 of Brodmann: A lesion in this area leads to a defect in understanding the significance of sensory information, which is called agnosia. A lesion that destroys a large portion of this association cortex causes tactile agnosia and astereognosis which are closely related. This is the condition when a person is unable to recognize the objects held in the hand, while the eyes are closed. He is unable to correlate the surface, texture, shape, size, and weight of the object or to compare the sensations with previous experience.</p>\n<p><strong>Highyeild:</strong></p><p>Secondary sensory area (SmII) Secondary sensory area is located in the upper lip of the posterior ramus of the lateral sulcus. The face area lies most anterior and the leg area is posterior. The whole body is represented bilaterally. This area relates more to pain perception. The ablation of this area may relieve intractable pain.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. First somesthetic or general sensory area (areas 3,1 and 2 of Brodmann): When this part of cortex is the site of destructive lesion, a crude form of awareness persists for the sensation of pain, heat, and cold on the opposite side of the There is poor localization of stimulus. Option: C. Motor speech area of Broca occupies the opercular and triangular portions of the inferior frontal gyrus corresponding to the areas 44 and 45 of Brodmann. This is present on the left side in 98% of right-handed persons. Option: D. Receptive speech area of Wernicke(Area 40), also known as sensory language area. It consists of the auditory association cortex and adjacent parts of the inferior parietal lobule.</p>\n<p><strong>Extraedge:</strong></p><p>Primary sensory area (areas 3, 1, and 2 of Brodmann) Primary sensory area is located in the postcentral gyrus and extends into the posterior part of the paracentral lobule on the medial surface of the hemisphere. The opposite half of the body is represented upside down exactly in the same fashion as in the primary motor area. Similarly, the area of the cortex assigned for a particular part is not proportional to the size of that part but to its functional significance (i.e. to the intricacies of sensations received from it). Thus, the thumb, fingers, lips, and tongue have a disproportionately large representation. The primary sensory area is concerned with the perception of exteroceptive (pain, touch, and temperature) and proprioceptive (vibration, muscle, and joint sense) sensations from the opposite half of the body. However, sensations from the pharynx, larynx, and perineum go to both sides.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 35 year old man presented with a defective vision in both eyes. On examination, it was superior quadrantanopia and there is damage to geniculocalcarine fibers to the visual cortex. Where do these fibers start?", "options": [{"label": "A", "text": "Medial Geniculate Body", "correct": false}, {"label": "B", "text": "lateral geniculate body", "correct": true}, {"label": "C", "text": "Internal capsule", "correct": false}, {"label": "D", "text": "Optic chiasma", "correct": false}], "correct_answer": "B. lateral geniculate body", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>lateral geniculate body The visual area is located above and below the calcarine sulcus on the medial surface of the occipital lobe. It corresponds to area 17 of Brodmann. The chief source of afferent fibers to area 17 is the lateral geniculate nucleus of the thalamus by way of geniculocalcarine tract.</p>\n<p><strong>Highyeild:</strong></p><p>Visual Pathway</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The medial geniculate body of the thalamus is the principal source of fibres ending in the auditory cortex with these fibres constituting the auditory radiation. There is spatial representation in the auditory area with respect to the pitch of sounds. Option: C. The internal capsule is a white matter structure situated in the inferomedial part of each cerebral hemisphere of the brain. It carries information past the basal ganglia, separating the caudate nucleus and the thalamus from the putamen and the globus pallidus. Option: D. Optic chiasma is the place in the brain where some of the optic nerve fibers coming from one eye cross optic nerve fibers from the other eye.</p>\n<p><strong>Extraedge:</strong></p><p>Frontal eye field (area 8 of Brodmann) The frontal eye field is located in the posterior part of the middle frontal gyrus just anterior to the facial area of the precentral gyrus. The electrical stimulation of this region causes deviation of both the eyes especially to the opposite side (conjugate movements of the eyes). The frontal eye field controls voluntary scanning movements of the eyes and is independent of the visual stimuli. The frontal eye field is connected to the visual area of the occipital cortex by association fiber. The involuntary following of moving objects by the eyes involves the visual area of the occipital cortex.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 72 year old man was brought to OPD with complaints of mental confusion, forgetfulness, irritability, and meaningless repetition of his own words. It was diagnosed as Alzheimer's disease. The changes of normal aging in the brain are more pronounced. Which among them are true regarding normal aging changes in the brain?", "options": [{"label": "A", "text": "Diminished Sulci", "correct": false}, {"label": "B", "text": "Wide gyri", "correct": false}, {"label": "C", "text": "Ventricle enlargement", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above Aging: Usually after 60–70 years or so there are changes in the brain. These are:</p>\n<p><strong>Highyeild:</strong></p><p>As age increases our brains shrink in volume, particularly in the frontal cortex. As our vasculature ages and our blood pressure rises the possibility of stroke and ischemia increases and our white matter develops lesions. Memory decline also occurs with aging and brain activation becomes more bilateral for memory tasks.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Prominence of sulci due to cortical shrinkage. Ventricular enlargement and sulcal widening were defined as an increase in ventricular size or sulcal size of 3 of 10 grades between baseline and follow-up. Option: B. The gyri get narrow and the sulci get broad. Cerebral cortex is folded into gyri which are separated from each other by sulci. This pattern increases the surface area of the cortex in a healthy human brain. Option: C. There is an enlargement of the ventricles. Hydrocephalus is the abnormal enlargement of ventricles caused by a build-up of cerebrospinal fluid (CSF).</p>\n<p><strong>Extraedge:</strong></p><p>Some areas of the brain decrease in size by up to 1% per year in some people but without any loss of function. Age-related changes in brain structure do not always result in loss of brain function. A decrease in brain function with aging may be the result of numerous factors that include changes in neurotransmitters, neurons, toxic substances that accumulate in the brain over time, and inherited changes. Short-term memory and the ability to learn new material tend to be affected relatively early. Verbal abilities, including vocabulary and word usage, may begin to decline later. Intellectual performance (the ability to process information, regardless of speed) is usually maintained if no underlying neurologic or vascular disorders are present.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 25 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The marked cell inhibits which of the following:", "options": [{"label": "A", "text": "Thalamus", "correct": false}, {"label": "B", "text": "Cerebral cortex", "correct": false}, {"label": "C", "text": "Vestibular nucleus", "correct": false}, {"label": "D", "text": "Deep cerebellar nuclei", "correct": true}], "correct_answer": "D. Deep cerebellar nuclei", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392034070-QTDA059001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deep cerebellar nuclei Marked cell- Purkinje cell in the slide of the cerebellum Axon from Purkinje cell inhibits the cerebellar nuclei</p>\n<p><strong>Highyeild:</strong></p><p>The cerebellar cortex contains three layers: Molecular layer : It consists of unmyelinated nerve fibres derived from the parallel fibres of axons of granule cells, stellate and basket cells, sensory climbing fibres, and dendrites of Purkinje and Golgi cells. It also contains stellate and basket cells Intermediate layer: It contains a single layer of cell bodies of Purkinje cells. Inner layer: Made up of cell bodies and dendrites of granule cells, Golgi cells. The Purkinje cell of the cerebellum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Thalamus Option: B. Cerebral cortex Option: C. Vestibular nucleus The marked cell is the Purkinje cell in the slide of the cerebellum, and Axon from the Purkinje cell inhibits the cerebellar nuclei. Therefore Options A, B and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>All the intrinsic neurons of the cerebellar cortex are inhibitory except granule cells. Such a collection of inhibitory neurons is not found anywhere else in the CNS except in the cerebellum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The primary visual area is located in the walls of:", "options": [{"label": "A", "text": "Parieto Occipital Sulcus", "correct": false}, {"label": "B", "text": "Superior temporal sulcus", "correct": false}, {"label": "C", "text": "Posterior part of calcarine sulcus", "correct": true}, {"label": "D", "text": "Central sulcus", "correct": false}], "correct_answer": "C. Posterior part of calcarine sulcus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior part of calcarine sulcus The primary visual area (Brodmann area 17) is located at the posterior part of the calcarine sulcus. The visual area is also called the striate area because the cortex here contains the line of Gennari, which is visible to the unaided eye. It is supplied by the posterior cerebral artery and additionally by the middle cerebral artery</p>\n<p><strong>Highyeild:</strong></p><p>The primary visual cortex (Brodmann area 17 ) is also known as the calcarine cortex, striate cortex, or V1. It is the main site of input of signals coming from the retina. It is located on the medial aspect of the occipital lobe, in the gyrus superior and inferior to the calcarine sulcus. Most of the cortex lies within the deep walls of the calcarine sulcus. The term striate cortex comes from its histological appearance in which the white-matter tracts of afferent fibres within lamina IV (the outer line of Baillarger) are visible to the naked eye and are known as the line of Gennari.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Parieto Occipital Sulcus Option: B. Superior temporal sulcus Option: D. Central sulcus The primary visual cortex (Brodmann area 17) is located in and on either side of the calcarine sulcus's posterior part, on the occipital lobe's medial surface. It functions primarily in discerning the intensity, shape, size, and location of objects in the visual field. Therefore options A, B, and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The primary visual cortex is supplied mainly by the calcarine artery but can also receive blood from the parieto-occipital and posterior temporal arteries.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The primary motor area is Brodmann's number:", "options": [{"label": "A", "text": "1", "correct": false}, {"label": "B", "text": "4", "correct": true}, {"label": "C", "text": "5", "correct": false}, {"label": "D", "text": "7", "correct": false}], "correct_answer": "B. 4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4 Primary motor area (area 4 of Brodmann) The primary motor area is in the precentral gyrus on the superolateral surface. It extends to the paracentral lobule's anterior part on the cerebral hemisphere's medial surface. It contains many pyramidal cells, including large ones (of Betz). About 40% of pyramidal (corticospinal and corticonuclear) fibres arise from this area.</p>\n<p><strong>Highyeild:</strong></p><p>Functional area of the Brain The functional areas on the superolateral surface of the left cerebral hemisphere. The functional areas on the inferomedial surface of the right cerebral hemisphere.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Primary sensory area (areas 3, 1 and 2 of Brodmann) The primary sensory area is located in the postcentral gyrus and extends into the paracentral lobule's posterior part on the hemisphere's medial surface. Option C. The sensory association area occupies the superior parietal lobule corresponding to the Areas 5 and 7 of Brodmann. It is concerned with perceiving the object's shape, size, roughness, and texture. Thus, it enables the individual to recognise the objects placed in his/her hand without seeing them. Such ability is referred to as stereognosis. Option D. The sensory association area occupies the superior parietal lobule corresponding to the Areas 5 and 7 of Brodmann. It is concerned with the perception of the objects' shape, size, roughness, and texture. Thus, it enables the individual to recognise the objects placed in his/her hand without seeing them. Such ability is referred to as stereognosis.</p>\n<p><strong>Extraedge:</strong></p><p>The secondary sensory area is located in the upper lip of the posterior ramus of the lateral sulcus. The face area lies most anterior, and the leg area is posterior. The whole body is represented bilaterally. This area relates more to pain perception. The ablation of this area may relieve intractable pain.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is a complete sulcus?", "options": [{"label": "A", "text": "Lunate", "correct": false}, {"label": "B", "text": "Parieto-occipital sulcus", "correct": false}, {"label": "C", "text": "Collateral", "correct": true}, {"label": "D", "text": "Central", "correct": false}], "correct_answer": "C. Collateral", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Collateral The complete sulcus is very deep, causing elevation in the walls of the lateral ventricle. Examples are the collateral and calcarine sulcus. Incomplete sulci are superficially situated and are not very deep, E.g. paracentral sulcus.</p>\n<p><strong>Highyeild:</strong></p><p>Types of Sulci: According to function The limiting sulcus separates two different areas functionally and structurally at its floor. For example, the central sulcus between the motor and sensory areas. The axial sulcus develops in the long axis of a rapidly growing homogeneous area. For example, the post-calcarine sulcus in the long axis of the striate area. The operculated sulcus is separated by its lips in two areas and contains a third area in the walls of the sulcus, e.g. the lunate sulcus. According to formation Primary sulci formed before birth independently. An example is the central sulcus. The secondary sulcus is produced by factors other than exuberant growth in the adjoining areas of the cortex. Examples are the lateral and parieto-occipital sulcus. According to depth The complete sulcus is very deep, causing elevation in the walls of the lateral ventricle. Examples are the collateral and calcarine sulcus. Incomplete sulci are superficially situated and are not very deep, e.g. precentral sulcus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Lunate The operculated sulcus is separated by its lips in two areas and contains a third area in the walls of the sulcus, e.g. the lunate sulcus. Option: B. Parieto-occipital sulcus The secondary sulcus is produced by factors other than exuberant growth in the adjoining areas of the cortex. Examples are the lateral and parieto-occipital sulcus. Option D. Central The limiting sulcus separates two different areas functionally and structurally at its floor. For example, the central sulcus between the motor and sensory areas.</p>\n<p><strong>Extraedge:</strong></p><p>The calcarine sulcus begins near the occipital pole in two converging rami. It runs forward to a point a little below the splenium of the corpus callosum. Here, the medial part of the parieto-occipital sulcus joins it at an acute angle. The anterior part of this sulcus gives rise to the prominence of the calcar avis in the posterior cornu of the lateral ventricle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Cortical representation of the body in the cerebrum is", "options": [{"label": "A", "text": "Horizontal", "correct": false}, {"label": "B", "text": "Vertical", "correct": true}, {"label": "C", "text": "Tandem", "correct": false}, {"label": "D", "text": "Oblique", "correct": false}], "correct_answer": "B. Vertical", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Vertical The cortical representation of the body is upside down (vertical) in an inverted direction - inverted homunculus. Representation depends on the skill, not the size of the organ.</p>\n<p><strong>Highyeild:</strong></p><p>Primary motor area The human body is upside-down in the precentral gyrus (inverted homunculus), as shown in the image below. The pharyngeal region and tongue are represented in the lowermost part, followed by the face, hand, trunk and thigh. The legs, feet and perineum are represented on the medial surface of the hemisphere in the paracentral lobule. The motor (A) and sensory (B) homunculi show proportional somatotopic representation in the main motor and sensory cortex.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Horizontal Option: C. Tandem Option: D. Oblique The cortical representation of the body is upside down (vertical) in an inverted direction - inverted homunculus. Representation depends on the skill, not the size of the organ. Therefore, Options A, C and D are all incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Lesions of the primary sensory area lead to the loss of appreciation of exteroceptive and proprioceptive sensations from the opposite half of the body. The crude pain, temperature, and touch sensations often return, but this is believed to be due to functions of the thalamus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During treatment of meningioma, the left paracentral lobule was injured. It would lead to paresis of:", "options": [{"label": "A", "text": "Right leg and perineum", "correct": true}, {"label": "B", "text": "left leg and perineum", "correct": false}, {"label": "C", "text": "Right shoulder and trunk", "correct": false}, {"label": "D", "text": "left shoulder and trunk", "correct": false}], "correct_answer": "A. Right leg and perineum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right leg and perineum Primary Motor Area is located in the precentral gyrus, including the anterior wall of the central sulcus, and in the paracentral lobule's anterior part on the cerebral hemispheres' medial surface. This corresponds to area 4 of Brodmann. Electrical stimulation of the primary motor area elicits muscle contraction mainly on the opposite side of the body. The contralateral half of the body is represented as upside down, except the face. The pharyngeal region and tongue are represented in the most ventral and lower part of the precentral gyrus, followed by the face, hand, arm, trunk and thigh. The leg, foot and perineum are on the medial surface of the hemisphere in the paracentral lobule.</p>\n<p><strong>Highyeild:</strong></p><p>The lesions of the primary motor area in one hemisphere produce flaccid paralysis of the extremities of the opposite half of the body (hemiplegia) . The masticatory, laryngeal, pharyngeal, upper facial and extraocular muscles are spared for being represented bilaterally.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. left leg and perineum Electrical stimulation of the primary motor area elicits muscle contraction mainly on the opposite side of the body. In the patient, the left paracentral lobule was injured, so the right side of the body will be affected. Option: C. Right shoulder and trunk The left paracentral lobule was injured in the patient, and the leg, foot and perineum are on the medial surface of the hemisphere in the paracentral lobule. Option: D. left shoulder and trunk Electrical stimulation of the primary motor area elicits muscle contraction mainly on the opposite side of the body. In the patient, the left paracentral lobule was injured, so the right side of the body will be affected.</p>\n<p><strong>Extraedge:</strong></p><p>There is disproportionate registration of the individual parts of the The area of the cortex controlling a particular movement is proportional to the skill involved in performing that movement and not the bulk of muscle participating. Thus, the face, especially the lips, tongue, larynx and hand, have disproportionately larger areas, while the trunk and lower limb have smaller areas.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The sulcus separating the cuneus from the lingual gyrus is:", "options": [{"label": "A", "text": "Calcarine Sulcus", "correct": true}, {"label": "B", "text": "Rhinal sulcus", "correct": false}, {"label": "C", "text": "Parieto-occipital sulcus", "correct": false}, {"label": "D", "text": "Cuneal sulcus", "correct": false}], "correct_answer": "A. Calcarine Sulcus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Calcarine Sulcus The calcarine sulcus begins near the occipital pole in two converging rami. It runs forward to a point a little below the splenium of the corpus callosum. Here, the medial part of the parieto-occipital sulcus joins it at an acute angle. The anterior part of this sulcus gives rise to the prominence of the calcar avis in the posterior cornu of the lateral ventricle. The cuneus is above the calcarine sulcus, while the lingual gyrus is below it.</p>\n<p><strong>Highyeild:</strong></p><p>The calcarine fissure divides the occipital lobe into two parts: 1) lingual gyrus (inferior part) and 2) cuneus (superior part). The visual (calcarine) cortex consists of the gyri on either side of the fissure.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Rhinal sulcus The rhinal sulcus is located on the anteromedial surface of the temporal lobe. It curves in an anteroposterior direction and separates the uncus from the temporal pole. Some sources consider it to be an extension of the collateral sulcus. Option:C. Parieto-occipital sulcus The parieto-occipital sulcus is a very deep sulcus that crosses the posterior part of the hemisphere and divides the internal occipital lobe from the parietal and internal temporal lobes. Option:D. Cuneal sulcus The cuneus is a wedge-shaped region on the medial surface of the occipital lobe.</p>\n<p><strong>Extraedge:</strong></p><p>The collateral sulcus , also known as the medial occipitotemporal sulcus , runs anteroposteriorly on the inferior surface of the temporal lobe and occipital lobe. Anteriorly it is sometimes continuous with the rhinal sulcus. Anteriorly, it separates the fusiform gyrus laterally from the parahippocampal gyrus medially. Posteriorly, it separates the fusiform gyrus laterally from the lingual gyrus medially.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The gustatory cortex is situated in:", "options": [{"label": "A", "text": "Superior Parietal Gyrus", "correct": false}, {"label": "B", "text": "Inferior frontal gyrus", "correct": false}, {"label": "C", "text": "Posterior ramus of lateral sulcus", "correct": true}, {"label": "D", "text": "Inferior temporal gyrus", "correct": false}], "correct_answer": "C. Posterior ramus of lateral sulcus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior ramus of lateral sulcus The taste area (gustatory area) is located in the dorsal wall of the posterior ramus of the lateral sulcus, with extension into the insula and corresponds to area 43 of Brodmann. It places the taste area adjacent to the first sensory area of the cortex for the tongue and pharynx. Its location is similar to the second somesthetic area.</p>\n<p><strong>Highyeild:</strong></p><p>Vestibular area is probably located near that part of the postcentral gyrus concerned with the sensations of the face. Olfactory area (Brodmann's area 28) is located in the anterior part of the parahippocampal gyrus and uncus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Superior Parietal Gyrus The superior parietal lobule is involved with spatial orientation and receives much visual input and sensory input from one's hand. It is also involved with other functions of the parietal lobe in general. Damage to the superior parietal lobule can cause contralateral astereognosis and hemispatial neglect. Option: B. Inferior frontal gyrus The motor speech area of Broca is located in the pars triangularis (area 45), and pars opercularis (area 44) of the inferior frontal gyrus of the frontal lobe of the left hemisphere (dominant hemisphere) in most of the individuals, and the persons are right handed. Option: D. Inferior temporal gyrus The middle and inferior temporal gyrus subserve language and semantic memory processing, visual perception, and multimodal sensory integration.</p>\n<p><strong>Extraedge:</strong></p><p>Comparison between motor and sensory aphasias Motor (Broca's) aphasia Sensory (Wernicke's) aphasia Site of lesion Posterior part of inferior frontal gyrus (areas 44, 45) Posterior part of superior temporal gyrus and adjoining part of the inferior parietal lobule (areas 22, 39, and 40) Speech Effortful, dysarthric, telegraphic, and nonfluent Fluent Comprehension of spoken speech Good Poor Ability to read, write, and calculate Intact Lost World blindness (inability to comprehend written speech) Absent Present</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 18 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which of the following is an example of an atavistic epiphysis?", "options": [{"label": "A", "text": "Greater Trochanter", "correct": false}, {"label": "B", "text": "Head of Femur", "correct": false}, {"label": "C", "text": "Upper End of Radius", "correct": false}, {"label": "D", "text": "Coracoid Process of Scapula", "correct": true}], "correct_answer": "D. Coracoid Process of Scapula", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Coracoid Process of Scapula These are independent bones in Lower animals but have united in humans with other bones. Coracoid process - Atavistic epiphysis</p>\n<p><strong>Highyeild:</strong></p><p>The clavipectoral fascia is traversed by: Lymphatics: passing between infraclavicular and apical nodes of the axilla Cephalic vein Lateral pectoral nerve Thoracoacromial vessels</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Greater Trochanter Traction epiphysis: The regions of the long bone which are non-articular, i.e. not involved in joint formation. Examples of traction epiphyses are tubercles of the humerus ( greater tubercle and lesser tubercle), and trochanters of the femur (greater and lesser). Option: B. Head of the femur Pressure epiphysis : The region of the long bone that forms the joint is a pressure epiphysis (for example- the head of the femur, part of the hip joint complex). Pressure epiphysis assists in transmitting the weight of the human body and is th e region of the bone tha t is under pressure during movement or locomotion. Another example of a pressure epiphysis is the head of the humerus which is part of the shoulder complex. condyles of the femur and tibia also come under the pressure of epiphysis. Option: C. Upper end of radius The upper end of the radius also forms the elbow joint so it is another example of pressure epiphysis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The intracapsular articular disc is present in which joint?", "options": [{"label": "A", "text": "Sternoclavicular Joint", "correct": true}, {"label": "B", "text": "Elbow joint", "correct": false}, {"label": "C", "text": "Hip joint", "correct": false}, {"label": "D", "text": "Carpal joint", "correct": false}], "correct_answer": "A. Sternoclavicular Joint", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sternoclavicular Joint The articular disc is seen in the temporomandibular joint and Sternoclavicular joint. The articular disc of the sternoclavicular joint is flat and nearly circular, interposed between the articulating surfaces of the sternum and clavicle. It is attached, above, to the upper and posterior border of the articular surface of the clavicle; below, to the cartilage of the first rib, near its junction with the sternum; and by its circumference to the interclavicular and anterior and posterior sternoclavicular ligaments. It is thicker at the circumference, especially its upper and back parts than at its center. It divides the joint into two cavities, each of which is furnished with a synovial membrane.</p>\n<p><strong>Highyeild:</strong></p><p>The clavipectoral fascia is traversed by: Lymphatics: passing between infraclavicular and apical nodes of the axilla Cephalic vein Lateral pectoral nerve Thoracoacromial vessels</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The axillary nerve is accompanied by which artery in the quadrangular intermuscular space?", "options": [{"label": "A", "text": "Axillary", "correct": false}, {"label": "B", "text": "Subscapular", "correct": false}, {"label": "C", "text": "Anterior circumflex humeral", "correct": false}, {"label": "D", "text": "Posterior circumflex humeral", "correct": true}], "correct_answer": "D. Posterior circumflex humeral", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior circumflex humeral Both the axillary nerve and posterior circumflex humeral artery traverse through quadrangular space in the scapular region. Spaces in the Scapular Region</p>\n<p><strong>Highyeild:</strong></p><p>The clavipectoral fascia is traversed by: Lymphatics: passing between infraclavicular and apical nodes of the axilla Cephalic vein Lateral pectoral nerve Thoracoacromial vessels</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Axillary The axillary artery as a whole does not traverse through any space of the scapular region. Option: B. Subscapular The circumflex s capular artery branch of the Subscapular artery traverses through the upper triangular space in the scapular region Option: C. Anterior circumflex humeral Anterior circumflex humeral arteries do not traverse through any scapular space.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The interosseous membrane of the forearm is pierced by:", "options": [{"label": "A", "text": "Brachial Artery", "correct": false}, {"label": "B", "text": "Anterior interosseous artery", "correct": true}, {"label": "C", "text": "Posterior interosseous artery", "correct": false}, {"label": "D", "text": "Ulnar recurrent artery", "correct": false}], "correct_answer": "B. Anterior interosseous artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior interosseous artery Anterior interosseous artery Anterior interosseous artery ( a branch of a common interosseous artery) runs on the anterior surface of the interosseous membrane. At the proximal border of the pronator quadratus, it pierces the interosseous membrane to reach the posterior forearm and anastomosis with the posterior interosseous artery.</p>\n<p><strong>Highyeild:</strong></p><p>The clavipectoral fascia is traversed by: Lymphatics: passing between infraclavicular and apical nodes of the axilla Cephalic vein Lateral pectoral nerve Thoracoacromial vessels</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Brachial Artery Option: C. Posterior interosseous artery Option: D. Ulnar recurrent artery Brachial, Posterior interosseous, and Ulnar recurrent arteries do not pierce the interosseous membrane of the forearm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The interosseous recurrent artery is a branch of :", "options": [{"label": "A", "text": "Anterior Interosseous Artery", "correct": false}, {"label": "B", "text": "Posterior interosseous artery", "correct": true}, {"label": "C", "text": "Common interosseous artery", "correct": false}, {"label": "D", "text": "Radial artery", "correct": false}], "correct_answer": "B. Posterior interosseous artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior interosseous artery Posterior interosseous artery Interosseous Recurrent artery The posterior interosseous artery gives off an interosseous recurrent branch that runs upwards and takes part in the anastomosis on the back of the lateral epicondyle of the humerus.</p>\n<p><strong>Highyeild:</strong></p><p>The clavipectoral fascia is traversed by: Lymphatics: passing between infraclavicular and apical nodes of the axilla Cephalic vein Lateral pectoral nerve Thoracoacromial vessels</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Anterior Interosseous Artery Option: C. Common interosseous artery The common interosseous artery (about 1 cm long) arises from the ulnar artery, just below the radial tuberosity. It passes backward to reach the upper border of the interosseous membrane and ends by dividing into the anterior and posterior interosseous arteries. Option: D. Radial artery The radial artery arises from the bifurcation of the brachial artery in the antecubital fossa. The radial artery may be divided into three groups, corresponding with the three regions in which the vessel is situated. In the forearm Radial recurrent artery Palmar carpal branch of radial artery Superficial palmar branch of the radial artery At the wrist Dorsal carpal branch of radial artery In the hand Princeps pollicis artery Radialis indicis Deep palmar arch</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 15 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The type of connective tissue present in the arrow-marked area is:", "options": [{"label": "A", "text": "Loose and Irregular", "correct": false}, {"label": "B", "text": "Specialized", "correct": false}, {"label": "C", "text": "Dense irregular", "correct": true}, {"label": "D", "text": "Dense regular", "correct": false}], "correct_answer": "C. Dense irregular", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391481846-QTDA034001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Dense irregular It is called so because of the irregular arrangement of tissue fibers. Marked structure–dermis of the skin This photomicrograph illustrates a section of the skin called the dermis. This region contains dense irregular connective tissue and collagen-producing Here, the collagen fibers show a very random and irregular orientation. Adjacent to the dense irregular connective tissue is adipose tissue with numerous adipose cells. Tissue preparation dissolves the lipids in individual adipose cells, and cell cytoplasm appears empty with only flattened, dense-staining nuclei in the peripheries. The Dermis of the skin also contains numerous sweat glands. The light-staining regions are the secretory cells of the sweat gland. In contrast, the dark-staining cells form the stratified cuboidal epithelium of the excretory ducts, which continue through the connective tissue and the stratified squamous epithelium of the skin to the surface of the skin. Dermis of the skin</p>\n<p><strong>Highyeild:</strong></p><p>Basic components of connective tissue</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Loose and Irregular Loose (areolar) connective tissue has a sparse, irregular network of collagen and elastic fibers suspended within a relatively large amount of ground substance. Option: B. Specialized Specialized connective tissues include adipose, cartilage, bone, blood, and lymphatic tissues. Option: D. Dense regular Dense regular connective tissue is mainly made up of type I collagen fibers. It is found in areas of the body where large amounts of tensile strength are required, like in ligaments, tendons, and aponeurosis. The collagen fibers are densely packed together and arranged in parallel to each other.</p>\n<p><strong>Extraedge:</strong></p><p>Scheme to show how collagen fibers are synthesized</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Ear lobule is made up of:", "options": [{"label": "A", "text": "Elastic Cartilage", "correct": true}, {"label": "B", "text": "Hyaline cartilage", "correct": false}, {"label": "C", "text": "Fibrocartilage", "correct": false}, {"label": "D", "text": "All", "correct": false}], "correct_answer": "A. Elastic Cartilage", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Elastic Cartilage Elastic cartilage: Points of identification: Elastic cartilage is characterized by chondrocytes within lacunae surrounded by bundles of elastic fibers. The perichondrium is present sbrous and the inner cellular layers. The tip of the nose also contains elastic cartilage. Examples: the Auricle (or pinna) and the lateral part of the external acoustic meatus, the medial part of the auditory tube, epiglottis, and two small laryngeal cartilages (corniculate and cuneiform).</p>\n<p><strong>Highyeild:</strong></p><p>Elastic Cartilage Elastic cartilage (or yellow fibrocartilage) is similar to hyaline cartilage. The main difference between hyaline cartilage and elastic cartilage is that instead of collagen fibers, the matrix contains numerous elastic fibers that form a network. The fibers are difficult to see in hematoxylin and eosin-stained sections, but they can be visualized if special methods for staining elastic fibers are used. The surface of elastic cartilage is covered by perichondrium.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Hyaline cartilage Option: C. Fibrocartilage Option: D. All The ear lobule is made of elastic cartilage. Therefore, options B, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Collagen Fibers of Cartilage The collagen fibers present in cartilage are (as a rule) chemically distinct from those in most other tissues. They are described as type II collagen. However, fibrocartilage and the perichondrium contain the normal type I collagen.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Conversion of chondrocytes to osteocytes occurs in which cartilage:", "options": [{"label": "A", "text": "Hyaline", "correct": true}, {"label": "B", "text": "Elastic", "correct": false}, {"label": "C", "text": "Fibrocartilage", "correct": false}, {"label": "D", "text": "None", "correct": false}], "correct_answer": "A. Hyaline", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Hyaline PROCESS OF (OSSIFICATION) BONE FORMATION Endochondral Ossification: Most bones develop by this process, with a hyaline cartilage model preceding bone. The hyaline cartilage model grows in length and width, then calcifies, and chondrocytes die. Mesenchymal cells in the periosteum differentiate into osteoprogenitor cells and form osteoblasts. Osteoblasts synthesize the osteoid matrix, which calcifies and traps osteoblasts in lacunae as osteocytes. Osteocytes establish cell-to-cell communication via canaliculi that open into blood channels. The primary ossification center forms in the diaphysis, and the secondary center in the epiphysis. The epiphyseal plate between the diaphysis and epiphysis allows for growth in bone length. Eventually, all cartilage is replaced by bone except the articular cartilage. Most bones undergo endochondral ossification except flat bones like skull bones which undergo intramembranous ossification.</p>\n<p><strong>Highyeild:</strong></p><p>Hyaline cartilage is characterized by isogenous groups of chondrocytes called cell nests. Chondrocytes are surrounded by a homogeneous basophilic matrix that separates the cells widely. Chondrocytes increase in size from periphery to center. Near the cartilage surface, the cells are flattened and merge with the cells of the overlying connective tissue. This connective tissue forms the perichondrium. Perichondrium displays an outer fibrous and inner cellular layer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Elastic Option: C. Fibrocartilage Option: D . None Most bones develop by endochondral ossification process, with a hyaline cartilage model preceding bone. Therefore options B, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Elastic cartilage is characterized by chondrocytes within lacunae surrounded by bundles of elastic fibers. The perichondrium is present, showing an outer fibrous and inner cellular layer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An image of Haematoxylin and Eosin (H&E) stained tissue sections is shown below. The tissue shown in the lower two-thirds of this picture is found is:", "options": [{"label": "A", "text": "Articular Disc", "correct": false}, {"label": "B", "text": "Intervertebral disc", "correct": false}, {"label": "C", "text": "Epiphyseal plates", "correct": true}, {"label": "D", "text": "Pinna of ear", "correct": false}], "correct_answer": "C. Epiphyseal plates", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391482165-QTDA034004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Epiphyseal plates Given image – hyaline cartilage-Hyaline cartilage contains multiple chondrocytes arranged in lacunae and groups. Seen in epiphyseal cartilage</p>\n<p><strong>Highyeild:</strong></p><p>HYALINE CARTILAGE Most common cartilage in the body and serves as a skeletal model for most bones. In developing bones, cartilage in epiphyseal plates allows bone growth in length. Replaced by bone after calcification and endochondral ossification in certain areas Contains type II collagen fibrils, which are not seen in histologic sections due to a reflective index similar to that of ground substance In adults, perichondrium surrounds hyaline cartilage except on bone-articulating surfaces. It does not calcify on the articular surfaces of bones, ends of ribs (costal cartilage), the nose, larynx, trachea, and in bronchi.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Articular Disc Articular Disc is an example of fibrocartilage. Option: B. Intervertebral disc An intervertebral disc is an example of fibrocartilage. Option: D. Pinna of ear The Pinna of the ear is an example of elastic cartilage.</p>\n<p><strong>Extraedge:</strong></p><p>In growing children, long bones consist of a bony diaphysis (corresponding to the shaft) and one or more bony epiphyses (corresponding to bone ends or projections). Each epiphysis is connected to the diaphysis by a plate of hyaline cartilage called the epiphyseal plate. This plate is essential for bone growth.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is a holocrine gland?", "options": [{"label": "A", "text": "Sweat Gland", "correct": false}, {"label": "B", "text": "Breast", "correct": false}, {"label": "C", "text": "Pancreas", "correct": false}, {"label": "D", "text": "Sebaceous Gland", "correct": true}], "correct_answer": "D. Sebaceous Gland", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sebaceous Gland Sebaceous Gland is an example of a holocrine gland.</p>\n<p><strong>Highyeild:</strong></p><p>Multicellular Exocrine Glands Based on the mode of secretion, they can be classified as follows: Merocrine: It is a type of exocrine gland. The secretion is released by exocytosis without losing a part of the secretory cell, g., salivary glands, some sweat glands, and the pancreas. Apocrine: Small apical part of the cell is released along with secretory product, g., sweat glands in the axillae, areola, and nipples of the breast, ear canal, eyelids, wings of the nostril, perianal region, and some parts of the external genitalia. Holocrine: As the secretory cell matures, it dies and becomes the secretory product,g., the sebaceous or tarsal gland. So, holocrine glands are called so because the whole cell is involved or destroyed during secretion from the gland. Types of Glands</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Sweat Gland The sweat gland is an example of a merocrine gland. Option: B. Breast The breast is an example of an apocrine gland. Option: C. Pancreas The pancreas is an abdominal organ possessing both endocrine and exocrine functions. It produces a variety of hormones that mainly pertain to regulating blood sugar levels. As an exocrine gland, it secretes pancreatic fluid that contains bicarbonate and digestive enzymes.</p>\n<p><strong>Extraedge:</strong></p><p>Classification of glands</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "What is the location of Meissner’s corpuscles?", "options": [{"label": "A", "text": "Lucidum", "correct": false}, {"label": "B", "text": "Basale", "correct": false}, {"label": "C", "text": "Reticular dermis", "correct": false}, {"label": "D", "text": "Papillary dermis", "correct": true}], "correct_answer": "D. Papillary dermis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Papillary dermis Meissner’s corpuscles are located in the papillary layer of the dermis.</p>\n<p><strong>Highyeild:</strong></p><p>DERMIS: PAPILLARY AND RETICULAR LAYERS Papillary Layer Basement membrane separates the dermis from the epidermis. Is the superficial layer in the dermis and contains loose irregular connective tissue. Dermal papillae and epidermal ridges form evaginations and interdigitations. Connective tissue filled with fibers, cells, and blood vessels. Sensory receptors (Meissner corpuscles) are present in the dermal papillae, and Meissner corpuscles also help in 2-point discrimination. Reticular Layer Is the deeper and thicker layer in the dermis, filled with dense irregular connective tissue. Few cells are present, and collagen is type I. No distinct boundary between the papillary and reticular layers. Blends inferiorly with superficial fascia's hypodermis or subcutaneous layer (hypodermis). Contains arteriovenous anastomoses and sensory receptors Pacinian corpuscles. Concentric lamellae of collagen fibers surround myelinated axons in Pacinian corpuscles. Dermis and Epidermis of skin histological slide</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Lucidum Stratum lucidum, 2-3 cell layers, present in thicker skin found in the palms and soles, is a thin clear layer consisting of eleidin which is a transformation product of keratohyalin. Option: B. Basale The basal cell layer contains cells called melanocytes. Melanocytes produce the skin coloring or pigment known as melanin, which gives skin its tan or brown color and helps protect the deeper layers of the skin from the harmful effects of the sun. Option: C. Reticular dermis The reticular dermis has blood vessels and connective tissue that supports the skin. Hair follicles, oil and sweat glands, and other structures are also found in the reticular dermis. Contains arteriovenous anastomoses and sensory receptors Pacinian corpuscles.</p>\n<p><strong>Extraedge:</strong></p><p>There are two types of skin. Thin or hairy skin: The epidermis is very thin in this type of skin. It contains hair and is found in all other parts of the body except the palms and soles. Thick or glabrous skin: In this type of skin, the epidermis is very thick with a thick stratum corneum layer. It is found in the palms of hands and soles of feet and has no hair.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Reticular fibers of collagen tissues are present except:", "options": [{"label": "A", "text": "Thymus", "correct": true}, {"label": "B", "text": "Bone Marrow", "correct": false}, {"label": "C", "text": "Spleen", "correct": false}, {"label": "D", "text": "Lymph node", "correct": false}], "correct_answer": "A. Thymus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thymus Reticular fibers: Consist mainly of type III collagen; form a delicate netlike framework in different organs. Reticular fibers are composed of type III collagen synthesized by reticular cells . They form a fine meshwork that supports tissues like the liver, bone marrow, and the lymphatic system . Reticular fibers are absent in the thymus gland.</p>\n<p><strong>Highyeild:</strong></p><p>Type of Collagen Found in Type I Type II Bones, fibrocartilage, tendons, ligaments , fascia, connective tissue, skin and capsule Hyaline and elastic Type III Spleen, lymph nodes, bone marrow. Found in relation to smooth muscles and nerve fibers Type IV Basement membrane and lens capsule</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Bone Marrow Option: C. Spleen Option: D. Lymph node Reticular fibers are composed of type III collagen synthesized by reticular cells . They form a fine meshwork that supports tissues like the liver, spleen, bone marrow, and the lymphatic system . Therefore options B, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Epithelial Cells of the thymus gland (Epitheliocytes) Embryologically, these cells are derived from the endoderm lining the third pharyngeal pouch. The cells lose all contact with the pharyngeal wall. Later they become flattened and may branch. The cells form sheets covering the capsule's internal surface, the septa's surfaces, and the blood vessels' surfaces. The epithelial cells lying deeper in the lobule develop processes that join similar processes of other cells to form a reticulum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The dense and regular arrangement of collagen fibers is seen in all EXCEPT:", "options": [{"label": "A", "text": "Tendon", "correct": false}, {"label": "B", "text": "Ligament", "correct": false}, {"label": "C", "text": "Aponeurosis", "correct": false}, {"label": "D", "text": "Periosteum", "correct": true}], "correct_answer": "D. Periosteum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Periosteum The periosteum is a membrane that covers the outer surface of all bones, except at the articular surfaces (e., the parts within a joint space) of long bones. The endosteum lines the inner surface of the medullary cavity of all long bones. The periosteum comprises an outer fibrous layer and an inner cambium layer (osteogenic layer). The fibrous layer is of dense irregular connective tissue, containing fibroblasts, while the cambium layer is highly cellular, containing progenitor cells that develop into osteoblasts.</p>\n<p><strong>Highyeild:</strong></p><p>Dense irregular connective tissue randomly arranged fibers - dermis of the skin, capsules around the liver, spleen, and other organs, and fibrous sheath around bones. Dense regular connective tissue-parallel arranged fibers are present in tendons, ligaments, and aponeurosis. This regular arrangement of fibers helps in providing strength to tendons and ligaments.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Tendon Option: B. Ligament Option: C. Aponeurosis Dense regular connective tissue-parallel arranged fibers are present in tendons, ligaments, and aponeurosis. This regular arrangement of fibers helps strengthen tendons and ligaments. Therefore, Options A, B, and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The periosteum is attached to the bone by strong collagen fibers called Sharpey's, extending to the outer circumferential and interstitial lamellae. It also provides an attachment for muscles and tendons. The periosteum that covers the outer surface of the bones of the skull is known as the pericranium .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Osteoclasts are derived from:", "options": [{"label": "A", "text": "Osteoprogenitor Cells", "correct": false}, {"label": "B", "text": "Monocytes", "correct": true}, {"label": "C", "text": "Osteoblasts", "correct": false}, {"label": "D", "text": "Osteocytes", "correct": false}], "correct_answer": "B. Monocytes", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Monocytes Osteoclasts are large, multinucleated cells found along bone surfaces where resorption (removal of bone), remodeling, and repair of bone take place. Although osteoblasts and osteocytes arise from mesenchyme osteoprogenitor cell line, the osteoclasts are multinucleated cells that originate by fusion of blood or hematopoietic progenitor cells of the mononuclear macrophage–monocyte cell line of the red bone marrow. Monocytes undergo differentiation to form various types of cells in different tissues like macrophages, osteoclasts, etc.</p>\n<p><strong>Highyeild:</strong></p><p>An osteoclast 'bone' is a type of bone cell that breaks down bone tissue . This function is critical in the maintenance, repair, and remodeling of bones of the vertebral skeleton . The osteoclast disassembles and digests the composite of hydrated protein and mineral at a molecular level by secreting acid and a collagenase , a process known as bone resorption . This process also helps regulate the level of blood calcium .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Osteoprogenitor Cells Osteoprogenitor cells can arise from stem cells in various tissues. There are no unique identifying markers for the mesenchymal stem cell (MSC) that give rise to bone, fat, cartilage, and muscle. Option: C. Osteoblasts Osteoblasts and osteocytes arise from the mesenchyme osteoprogenitor cell line. Option: D. Osteocytes Osteoblasts and osteocytes arise from the mesenchyme osteoprogenitor cell line.</p>\n<p><strong>Extraedge:</strong></p><p>Osteoclasts are found on those surfaces of bone that are undergoing resorption. On such surfaces, the osteoclasts are seen to be located in shallow depressions called resorption bays (Howship's lacunae) . The resorption bays are created by the erosive action of osteoclasts on the underlying bone. The border of the lower part of an osteoclast exhibits finger-like processes due to the presence of deep infoldings of the cell membrane ; this border is called the ruffled border. The ruffled border lies in contact with the bone surface within a resorption bay.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 32-year female following a road traffic accident recovers but with nasal deformity. For aesthetic concerns, she visited a rhinoplasty surgeon. Which of the following is true about the female nose in contrast to the male nose?", "options": [{"label": "A", "text": "Female nose is slightly larger and wider than the male nose", "correct": false}, {"label": "B", "text": "Female nose is slightly smaller and narrower than the male nose", "correct": true}, {"label": "C", "text": "Female nose is slightly larger and narrower than the male nose", "correct": false}, {"label": "D", "text": "Female nose is slightly smaller and wider than the male nose", "correct": false}], "correct_answer": "B. Female nose is slightly smaller and narrower than the male nose", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Female nose is slightly smaller and narrower than the male nose The proportions of the nose and face, both from in front and from the side, are of enormous significance to the rhino-plastic surgeon. Aesthetic proportions of the nose vary depending on sex, age, ethnicity, and facial characteristics; however, ranges of normality are described to assist in aesthetic assessment. The female nose is slightly smaller and narrower than the male nose; it is often slightly concave in profile view, with a slightly obtuse nasolabial angle (increased tip rotation). The width of the nose is roughly 70% of e length; the width of the alar base is usually equal to the intercanthal distance. But frontal and parietal eminences are larger in female skulls than male skulls.</p>\n<p><strong>Highyeild:</strong></p><p>The nasal cavity is an irregular space between the roof of the mouth and the cranial base. It is wider below than above and widest and vertically deepest in its central region, divided by a vertical, midline, osseocartilaginous septum. The bony part of the septum reaches the posterior limit of the cavity. The nasal cavity communicates with the paranasal sinuses and opens into the nasopharynx through a pair of oval openings, the posterior nasal apertures, or choanae. The latter is separated by the posterior border of the vomer, and each is limited above by the vaginal process of the medial pterygoid plates, laterally by the perpendicular plate of the palatine bone and the medial pterygoid plate, and below by the horizontal plate of the palatine bone</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Female nose is slightly smaller and narrower relative to the male nose. Option: C. Female nose is slightly smaller relative to the male nose. Option: D. Female nose is narrower relative to the male nose.</p>\n<p><strong>Extraedge:</strong></p><p>Nasal skin is innervated by the infratrochlear and external nasal branches of the nasociliary nerve (ophthalmic division, trigeminal nerve) and the nasal branch of the infraorbital nerve (maxillary division, trigeminal nerve).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the type of muscle shown in the figure.", "options": [{"label": "A", "text": "Cruciate", "correct": false}, {"label": "B", "text": "Spiral", "correct": true}, {"label": "C", "text": "Multipennate", "correct": false}, {"label": "D", "text": "Fusiform", "correct": false}], "correct_answer": "B. Spiral", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391482182-QTDA034011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spiral The shown muscle is pectoralis major. It inserts on the lateral lip of the bicipital groove. Spiral or twisted fibers are found in the trapezius, pectoralis major, latissimus dorsi, supinator, etc.</p>\n<p><strong>Highyeild:</strong></p><p>The muscles can be classified according to the arrangement of their fasciculi into the following groups: Parallel Fasciculi When the fasciculi are parallel to the line of pull, the muscle may be: Quadrilateral (thyrohyoid), Strap-like (sternohyoid and sartorius). Strap-like with tendinous intersections (rectus abdominis). Fusiform (biceps brachii, digastric, etc.). The range of movement in such muscles is maximum Oblique Fasciculi When the fasciculi are oblique to the line of pull, the muscle may be triangular or pennate (feather-like) in construction. This arrangement makes the muscle more powerful, although the range of movement is reduced. Oblique arrangements are of the following types: Triangular, e.g. temporalis, adductor longus. Unipennate, e.g. flexor pollicis longus, extensor digitorum longus, peroneus tertius, palmar interossei Bipennate, e.g. rectus femoris, dorsal interossei, peroneus longus, flexor hallucis longus. Multipennate, e.g., subscapularis, deltoid (acromial fibers). Circumpennate, e.g., tibialis anterior Spiral or Twisted Fasciculi Spiral or twisted fibers are found in the trapezius, pectoralis major, latissimus dorsi, supinator, etc. In certain muscles, the fasciculi are crossed. These are called cruciate muscles, e.g., sternocleidomastoid, masseter, and adductor magnus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Cruciate In certain muscles the fasciculi are crossed. These are called cruciate muscles,g., sternocleidomastoid, masseter, and adductor magnus. Option: C. Multipennate Multipennate muscle examples are, Subscapularis, and deltoid (acromial fibers). Option:D. Fusiform Fusiform muscle examples are, biceps brachii, digastric, etc. The range of movement in such muscles is maximum</p>\n<p><strong>Extraedge:</strong></p><p>Types of Muscle Striated Non-striated Cardiac 1. Striated muscles are present in the limbs, body wall, tongue, pharynx and beginning of oesophagus Oesophagus (distal part), urogenital tract, urinary bladder, blood vessels, iris of eye, arrector pilli muscle of hair Wall of heart 2. Long and cylindrical Spindle shaped Short and cylindrical 3. Fibres unbranched Fibres unbranched Fibres branched 4. Multinucleated Uninucleated Uninucleated 5. Bounded by sarcolemma Bounded by plasma- lemma Bounded by plasma- lemma 6. Light and dark bands present Light and dark bands absent Faint light and dark bands present 7. No intercalated disc No intercalated discs Intercalated disc present and a characteristic feature 8. Nerve supply from cranial nervous system No intercalated discs Intercalated disc present and a characteristic feature 9. Blood supply is abundant Nerve supply from autonomic nervous system Nerve supply from autonomic nervous system 10. Very rapid contraction Blood supply is scanty Blood supply is abundant 11. They soon get fatigued Slow contraction They do not get fatigued Rapid contractions They never get fatigued 12. Voluntary Involuntary Involuntary</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 21 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "In the given figure, identify A and B, respectively:", "options": [{"label": "A", "text": "Filum terminale internum and externum respectively", "correct": true}, {"label": "B", "text": "Filum terminale externum and internum, respectively", "correct": false}, {"label": "C", "text": "Filum terminale internum and cauda equina respectively", "correct": false}, {"label": "D", "text": "Cauda equina and Filum terminale internum, respectively", "correct": false}], "correct_answer": "A. Filum terminale internum and externum respectively", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392080178-QTDA060001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Filum terminale internum and externum respectively The filum terminale, a filament of connective tissue approximately 20 cm long, descends from the apex of the conus medullaris. Its upper 15 cm, the filum terminale internum, (A) is continued within extensions of the dural and arachnoid meninges and reaches the caudal border of the second sacral vertebra. Its final 5 cm, the filum terminale externum, (B) fuses with the investing dura mater and then descends to the dorsum of the first coccygeal vertebral segment. The filum is continuous above the spinal pia mater. Spinal cord</p>\n<p><strong>Highyeild:</strong></p><p>The spinal cord measures about 45 cm (18”) in adult males and 42 cm in adult females and weighs about 30 g. It extends as a downward continuation of medulla oblongata from the upper border of the posterior arch of the first cervical vertebra (C1) to the lower edge of the first lumbar vertebra (LI). Its lower tapering extremity is called conus medullaris . The apex of conus medullaris continues downwards as a thin, thread-like filament called filum terminale . The spinal cord provides attachment to 31 pairs of spinal nerves which connect it to the tissues of the trunk, girdles, limbs, and viscera.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. A capacious part of the subarachnoid space surrounds the filum terminale internum and is the usual access site for lumbar puncture. Option: C, D. A few strands of nerve fibres, which probably represent roots of rudimentary second and third coccygeal spinal nerves, adhere to its upper part. The central canal is continued into the filum for 5 to 6 mm.</p>\n<p><strong>Extraedge:</strong></p><p>Functions of the spinal cord The execution of simple reflexes. The transmission of impulses to and from the brain.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the sites mentioned above is the usual place for lumbar puncture?", "options": [{"label": "A", "text": "Subarachnoid", "correct": true}, {"label": "B", "text": "Filum terminale externum", "correct": false}, {"label": "C", "text": "Cauda equina", "correct": false}, {"label": "D", "text": "Conus medullaris", "correct": false}], "correct_answer": "A. Subarachnoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Subarachnoid The capacious part of the subarachnoid space surrounds the filum terminale internum and is the usual access site for lumbar puncture.</p>\n<p><strong>Highyeild:</strong></p><p>Lumbar puncture Lumbar puncture is done to withdraw cerebrospinal fluid for various diagnostic and therapeutic purposes. The puncture should be done well below the termination of the cord, i.e. lower border of LI. A horizontal line joining the highest points of the iliac crests passes through the spine of the fourth lumbar vertebra. Therefore, the interspinous spaces immediately above and below this landmark can be used safely. The interspinous space between L3 and L4 is the most preferred site. Because in this region, subarachnoid space is roomier and contains only filum terminale and roots of lumbar, sacral and coccygeal nerves forming the cauda equina. During this procedure, the spine must be fully flexed with the patient lying on the side or seated. So, the interspinous spaces are opened to their maximum extent, and the lower end of the spinal cord is slightly raised. The needle is passed inwards and somewhat crani- ally exactly in the midline. The supraspinous and interspinous ligaments are traversed, and then the dura mater is penetrated, with a distinct feel of ‘give way’. Occasionally, root pain is experienced if the roots of cauda equina are impinged upon, but usually, they float clear of the needle. Sagittal section through lumbosacral region showing conus medullaris, filum terminale (internum and externum), the lower end of subarachnoid space and site of lumbar puncture.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Its final 5 cm, the filum terminale externum, fuses with the investing dura mater and then descends to the dorsum of the first coccygeal vertebral segment. Option: C, D. A few strands of nerve fibres adhere to its upper part, probably representing the roots of the second and third coccygeal spinal nerves. The central canal is continued into the filum for 5 to 6 mm.</p>\n<p><strong>Extraedge:</strong></p><p>Positional Changes Of The Cord Up to the 3rd month of intrauterine development, the spinal cord extends throughout the entire vertebral canal, and the spinal nerves pass through the intervertebral foramina at their level of origin. After that, the vertebral column grows faster than the spinal cord, and the spinal cord's terminal end gradually shifts to a higher level. Consequently, at birth, the spinal cord ends at the level of the third lumbar vertebra, while in adulthood, it terminates at the level of the lower border of L1 (or the intervertebral disc between the LI and L2). The knowledge of these variations in the vertebral level of the lower end of the cord is essential to avoid injury to the cord while performing lumbar puncture, especially in children.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 50-year-old man has come to the emergency department for 5 hours because of urinary incontinence. His past medical history is non-contributory. He says the onset was sudden and accompanied by worsening back pain. Now he cannot feel anything as he wipes after voiding his bowel or bladder. He also feels \"pins and needles\" along both medial thighs. Which of the following is the most likely diagnosis?", "options": [{"label": "A", "text": "Cauda Equina", "correct": true}, {"label": "B", "text": "Conus medullaris", "correct": false}, {"label": "C", "text": "Lumbar disc herniation", "correct": false}, {"label": "D", "text": "Central cord syndrome", "correct": false}], "correct_answer": "A. Cauda Equina", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cauda Equina This is a case of cauda equina syndrome. Patients present with the following clinical findings: Back pain (most common) may be the initial presenting symptom alone Unilateral or bilateral leg pain (2nd most common) Saddle anesthesia Bladder dysfunction Unilateral or bilateral sensory changes in legs Unilateral or bilateral motor weakness in the legs</p>\n<p><strong>Highyeild:</strong></p><p>The symptoms and signs of cauda equina syndrome tend to be mostly lower motor neuron (LMN) in nature, while those of conus medullaris syndrome are a combination of LMN and upper motor neuron (UMN) effects. Conus medullaris syndrome is an incomplete spinal cord injury less likely to cause paralysis than other spinal cord injuries. Instead, the most common symptoms include: Severe back pain Strange or jarring sensations in the back, such as buzzing, tingling, or numbness Bowel and bladder dysfunction, such as difficulty controlling your elimination functions Sexual dysfunction Weakness, numbness, or tingling in your lower limbs Sensations in your lower limbs that aren't caused by a clinical issue. For instance, you might have itchiness in your leg that is not well-explained by an allergic reaction or another</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Conus medullaris Lesions around the vertebral L2 level can affect the conus medullaris, known as conus medullaris syndrome. Symptoms include sudden onset severe back pain, perianal anaesthesia, symmetric lower extremity motor weakness with hyperreflexia, and early onset bowel and bladder dysfunction. Option: C. Lumbar disc herniation It is common for a herniated disc to press against, or inflame, a nearby nerve, causing pain to radiate along the length of the nerve. A lumbar herniated disc is the most common cause of sciatica , leg pain along the sciatic nerve down the back of the leg. Option: D. Central cord syndrome Central cord syndrome is a clinical diagnosis with a presentation that includes disproportionate impairment of the upper limb motor function compared to the lower limbs, varying degrees of sensory deficits below the level of the spinal cord lesion and possibly urinary or gastrointestinal dysfunction.</p>\n<p><strong>Extraedge:</strong></p><p>Symptoms and Signs of Conus Medullaris and Cauda Equina Syndromes Conus Medullaris Syndrome Cauda Equina Syndrome Presentation Sudden and bilateral Gradual and unilateral Reflexes Knee jerks are preserved, but ankle jerks affected Both ankle and knee jerks affected Radicular pain Less severe More severe Low back pain More Less Sensory symptoms and signs Numbness tends to be more localised to the perianal area, symmetrical and bilateral; sensory dissociation occurs Numbness tends to be more localised to the saddle area; asymmetrical, may be unilateral; no sensory dissociation; loss of sensation in specific dermatomes in lower extremities with numbness and paresthesia; possible numbness in the pubic area, including glans penis or clitoris Motor strength Typically symmetric, hyperreflexic distal paresis of lower limbs that is less marked; fasciculations may be present Asymmetric areflexic paraplegia is more marked; fasciculations rare; atrophy more common Impotence Frequent Less frequent; erectile dysfunction that includes the inability to have an erection, inability to maintain an erection, lack of sensation in the pubic area (including glans penis or clitoris), and inability to ejaculate Sphincter dysfunction Urinary retention and atonic anal sphincter cause overflow urinary and fecal incontinence; tend to present early in the disease. Urinary retention; tends to present late in the course of the disease.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 25-year-old male presented with complaints of weakness of the lower limbs and urinary retention. It is diagnosed as cauda equina syndrome. Which are the nerve roots that form cauda equina?", "options": [{"label": "A", "text": "L2-L5,S1-S5,Co1", "correct": true}, {"label": "B", "text": "L1-L5,S1-S5,Co1", "correct": false}, {"label": "C", "text": "L2-L5,S1-S3,Co1", "correct": false}, {"label": "D", "text": "L1-L5,S1-S5", "correct": false}], "correct_answer": "A. L2-L5,S1-S5,Co1", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>L2-L5,S1-S5,Co1 Dorsal and ventral nerve roots of the right and left sides of L2 to L5, S1 to S5 and Co1 nerves lie almost vertically around the filum terminale. These are called cauda equina, as they resemble a horse’s tail. One segment's dorsal and ventral nerve roots join together at respective intervertebral foramen to exit as the spinal nerve.</p>\n<p><strong>Highyeild:</strong></p><p>The cauda equina is a bundle of spinal nerves and spinal nerve rootlets, consisting of the second through fifth lumbar nerve pairs, the first through fifth sacral nerve pairs, and the coccygeal nerve arise from the lumbar enlargement and the conus medullaris of the spinal cord. The cauda equina occupies the lumbar cistern, a subarachnoid space inferior to the conus medullaris. The nerves that compose the cauda equina innervate the pelvic organs and lower limbs, including motor innervation of the hips, knees, ankles, feet, internal anal sphincter and external anal sphincter. In addition, the cauda equina extends to sensory innervation of the perineum and, partially, parasympathetic innervation of the bladder.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. L1-L5,S1-S5,Co1 Option: C. L2-L5,S1-S3,Co1 Option: D. L1-L5, S1-S5 Dorsal and ventral nerve roots of the right and left sides of L2 to L5, S1 to S5 and Co1 nerves lie almost vertically around the filum terminale. These are called cauda equina, as they resemble a horse’s tail. Therefore, Options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The cauda equina exists within the lumbar cistern, a gap between the arachnoid membrane and the pia matter of the spinal cord, called the subarachnoid space. Cerebrospinal fluid also exists within this space. Because the spinal cord terminates at level L1/L2, lumbar puncture is performed from the lumbar cistern between two vertebrae at level L3/L4, or L4/L5, where there is no risk of accidental injury to the spinal cord, when a sample of CSF is needed for clinical purposes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 23-year-old female had a lower segment caesarian section, and spinal anaesthesia was given. It accidentally caused damage to her cauda equina nerve roots. How many nerve roots are at the beginning of cauda equina?", "options": [{"label": "A", "text": "20", "correct": false}, {"label": "B", "text": "16", "correct": false}, {"label": "C", "text": "30", "correct": false}, {"label": "D", "text": "40", "correct": true}], "correct_answer": "D. 40", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>40 There are 40 nerve roots at the beginning of cauda equina. These are the dorsal and ventral nerve roots of the right and left sides for each segment. So each segment has four nerve roots. Thus, there are 4 × 4 = 16 lumbar nerve roots; 4 × 5 = 20 sacral nerve roots; and 4 × 1 = 4 coccygeal nerve roots, making it 40 nerve roots. One dorsal root and one ventral root joining to form one spinal nerve and leaves through the foramen on one side. So at every intervertebral foramen, four nerve roots exit the cauda equina, leaving it thinner. In the end, only filum terminale remains to be attached to the coccyx.</p>\n<p><strong>Highyeild:</strong></p><p>Cauda equina syndrome (CES) is a condition that occurs when the bundle of nerves below the end of the spinal cord, known as the cauda equina, is damaged. Signs and symptoms include low back pain, pain that radiates down the leg, numbness around the anus, and loss of bowel or bladder control. Onset may be rapid or gradual. The cause is usually a disc herniation in the lower back region. Other causes include spinal stenosis, cancer, trauma, epidural abscess, and epidural hematoma. The diagnosis is suspected based on symptoms and confirmed by medical imaging such as MRI or CT scan.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. 20 Option: B. 16 Option: C. 30 There are 40 nerve roots at the beginning of cauda equina. These are the dorsal and ventral nerve roots of the right and left sides for each segment. So each segment has four nerve roots. Thus, there are 4 × 4 = 16 lumbar nerve roots; 4 × 5 = 20 sacral nerve roots; and 4 × 1 = 4 coccygeal nerve roots, making it 40 nerve roots. Therefore Options A, B and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Signs and symptoms of cauda equina syndrome include: Severe back pain Saddle anaesthesia, i.e., anaesthesia or paraesthesia involving S3 to S5 dermatomes, including the perineum, external genitalia and anus; or more descriptively, numbness or \"pins-and-needles\" sensations of the groin and inner thighs which would contact a saddle when riding a horse. Bladder and bowel dysfunction, caused by decreased tone of the urinary and anal sphincters. Detrusor weaknesses causing urinary retention and post-void residual incontinence as assessed by bladder scanning the patient after the patient has urinated. Sciatica-type pain on one side or both sides, although pain may be wholly absent Weakness of the muscles of the lower legs (often paraplegia) Achilles (ankle) reflex absent on both sides. Sexual dysfunction Absent anal reflex and bulbocavernosus reflex Gait disturbance Severe back pain, saddle anaesthesia, urinary or faecal incontinence and sexual dysfunction are considered \"red flags\", i.e. features that require urgent investigation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old male presented with spinal cord infection clinical features two weeks back. Now, he complained of severe back pain, saddle-shaped loss of sensation around genital areas, anal incontinence and sexual functions are affected. What is your diagnosis?", "options": [{"label": "A", "text": "Cauda Equina Syndrome", "correct": false}, {"label": "B", "text": "Conus medullaris syndrome", "correct": true}, {"label": "C", "text": "Brown Sequard syndrome", "correct": false}, {"label": "D", "text": "Medial medullary syndrome", "correct": false}], "correct_answer": "B. Conus medullaris syndrome", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Conus medullaris syndrome Conus medullaris syndrome: It is produced due to pressure on the conus medullaris of the spinal cord from where S2–S4 nerves arise. The symptoms and signs are Saddle-shaped anaesthesia on the bottom, loss of anal sphincteric reflex, and urinary bladder and bowel getting affected early. There is no motor weakness, and the patient has normal knee and ankle reflexes.</p>\n<p><strong>Highyeild:</strong></p><p>Symptoms and Signs of Conus Medullaris and Cauda Equina Syndromes Conus Medullaris Syndrome Cauda Equina Syndrome Presentation Sudden and bilateral Gradual and unilateral Reflexes Knee jerks are preserved, but ankle jerks affected Both ankle and knee jerks affected Radicular pain Less severe More severe Low back pain More Less Sensory symptoms and signs Numbness tends to be more localised to the perianal area, symmetrical and bilateral; sensory dissociation occurs Numbness tends to be more localised to the saddle area; asymmetrical, may be unilateral; no sensory dissociation; loss of sensation in specific dermatomes in lower extremities with numbness and paresthesia; possible numbness in the pubic area, including glans penis or clitoris Motor strength Typically symmetric, hyperreflexic distal paresis of lower limbs that is less marked; fasciculations may be present Asymmetric areflexic paraplegia is more marked; fasciculations rare; atrophy more common Impotence Frequent Less frequent; erectile dysfunction that includes the inability to have an erection, inability to maintain an erection, lack of sensation in the pubic area (including glans penis or clitoris), and inability to ejaculate Sphincter dysfunction Urinary retention and atonic anal sphincter cause overflow urinary and fecal incontinence; tend to present early in the disease. Urinary retention; tends to present late in the course of the disease. Region of cauda equina and medullaris syndrome</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Cauda equina syndrome: It occurs due to compression of cauda equina in the vertebral canal. L2-S5 nerve roots are affected. Its features are Loss of knee and ankle jerks, sensory loss in nerve root distribution, asymmetric areflexic lower motor neuron type of paralysis and later involvement of the bowel and bladder. Option: C. Brown-Séquard syndrome: The signs and symptoms are due to injury to one-half of the spinal cord. The following are at the level of damage: ipsilateral upper motor neuron paralysis, ipsilateral loss of conscious proprioception, and contralateral loss of pain and temperature. The following are due to injury to various tracts below the level of damage: Ipsilateral lower motor neuron paralysis and ipsilateral loss of sensation over the cranial dermatome. Option: D. Medial medullary syndrome: This syndrome occurs due to anterior spinal artery thrombosis. There is paralysis of the tongue muscles on the same side, associated with hemiplegia and loss of position sense in limbs on the opposite side.</p>\n<p><strong>Extraedge:</strong></p><p>The cauda equina exists within the lumbar cistern, a gap between the arachnoid membrane and the pia matter of the spinal cord, called the subarachnoid space. Cerebrospinal fluid also exists within this space. Because the spinal cord terminates at level L1/L2, lumbar puncture is performed from the lumbar cistern between two vertebrae at level L3/L4, or L4/L5, where there is no risk of accidental injury to the spinal cord, when a sample of CSF is needed for clinical purposes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old male presented with LMN type of lower limb paralysis with bladder involvement. The cauda equina fibres are affected. How many nerve roots exit the cauda equina at each intervertebral foramina?", "options": [{"label": "A", "text": "2", "correct": false}, {"label": "B", "text": "1", "correct": false}, {"label": "C", "text": "4", "correct": true}, {"label": "D", "text": "3", "correct": false}], "correct_answer": "C. 4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4 One dorsal root and one ventral root joining to form one spinal nerve and leaves through the foramen on one side. So at every intervertebral foramen, four nerve roots exit the cauda equina, leaving it thinner. In the end, only filum terminale remains to be attached to the coccyx.</p>\n<p><strong>Highyeild:</strong></p><p>There are 40 nerve roots at the beginning of cauda equina. These are the dorsal and ventral nerve roots of the right and left sides for each segment. So each segment has four nerve roots. Thus, there are 4 × 4 = 16 lumbar nerve roots; 4 × 5 = 20 sacral nerve roots; and 4 × 1 = 4 coccygeal nerve roots, making it 40 nerve roots. Dorsal and ventral nerve roots of the right and left sides of L2 to L5, S1 to S5 and Co1 nerves lie almost vertically around the filum terminale. One dorsal root and one ventral root joining to form one spinal nerve and leaves through the foramen on one side. So at every intervertebral foramen, 4 nerve roots exit the cauda equina, leaving it thinner. In the end, only filum terminale remains to be attached to the coccyx.</p>\n<p><strong>Extraedge:</strong></p><p>The cauda equina is a bundle of spinal nerves and spinal nerve rootlets, consisting of the second through fifth lumbar nerve pairs, the first through fifth sacral nerve pairs, and the coccygeal nerve arise from the lumbar enlargement and the conus medullaris of the spinal cord. The cauda equina occupies the lumbar cistern, a subarachnoid space inferior to the conus medullaris. The nerves that compose the cauda equina innervate the pelvic organs and lower limbs, including motor innervation of the hips, knees, ankles, feet, internal anal sphincter and external anal sphincter. In addition, the cauda equina extends to sensory innervation of the perineum and, partially, parasympathetic innervation of the bladder.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 34-year-old male presented with flaccid paralysis of lower limbs and root pain. It is diagnosed as cauda equina syndrome. Which segments are injured in cauda equina syndrome?", "options": [{"label": "A", "text": "L2-S5", "correct": true}, {"label": "B", "text": "L1-L5", "correct": false}, {"label": "C", "text": "S2-S4", "correct": false}, {"label": "D", "text": "L2-S2", "correct": false}], "correct_answer": "A. L2-S5", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>L2-S5 Cauda equina syndrome occurs due to compression of the cauda equina in the vertebral canal. L2–S5 nerve roots are affected. Its features are Loss of knee and ankle jerks, sensory loss in nerve root distribution, asymmetric areflexic lower motor neuron type of paralysis and later involvement of the bowel and bladder.</p>\n<p><strong>Highyeild:</strong></p><p>Conus medullaris syndrome is caused by an injury or insult to the conus medullaris and lumbar nerve roots. It is a clinical subset of spinal cord injury syndromes. Injuries at the T12 to L2 vertebrae level are most likely to result in conus medullaris syndrome. Region of cauda equina and medullaris syndrome</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. L1-L5 Option: C. S2-S4 Option: D. L2-S2 Cauda equina syndrome occurs due to compression of the cauda equina in the vertebral canal. L2–S5 nerve roots are affected. Therefore, Options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Patients present with conus medullaris syndrome present with a combination of severe back pain and upper and lower motor neuron deficits; unlike cauda equina syndrome, which will only have lower motor neurone deficits, conus medullaris will have a combination of upper and lower motor neurone involvement.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 54-year-old male presented with saddle-shaped anaesthesia on the bottom, anal incontinence, and difficulty passing stools. It is diagnosed as conus medullaris syndrome. Which segment of neurons is damaged here?", "options": [{"label": "A", "text": "S1-S2", "correct": false}, {"label": "B", "text": "S2-S4", "correct": true}, {"label": "C", "text": "S2-S5", "correct": false}, {"label": "D", "text": "All of these", "correct": false}], "correct_answer": "B. S2-S4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>S2-S4 The conus medullaris is the spinal cord's terminal end, typically occurring at the L1 vertebral level in the average adult. Conus medullaris syndrome: It is produced due to pressure on the conus medullaris of the spinal cord from where S2–S4 nerves arise.</p>\n<p><strong>Highyeild:</strong></p><p>The symptoms and signs are Saddle-shaped anaesthesia on the bottom, loss of anal sphincteric reflex, and urinary bladder and bowel getting affected early. There is no motor weakness, and the patient has normal knee and ankle reflexes. Cauda equina syndrome Conus medullaris syndrome Usually unilateral, severe radicular pain Sudden-onset severe back pain Saddle hypo/anaesthesia Perianal hypo/anaesthesia Asymmetric motor weakness Symmetric motor weakness Hyporeflexia/areflexia Hyperreflexia Late-onset bowel & bladder dysfunction Early-onset bowel & bladder dysfunction</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. S1-S2 Option: C. S2-S5 Option: D. All of these The conus medullaris is the spinal cord's terminal end, typically occurring at the L1 vertebral level in the average adult. Conus medullaris syndrome: It is produced due to pressure on the conus medullaris of the spinal cord from where S2–S4 nerves arise. Therefore, options A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The cauda equina exists within the lumbar cistern, a gap between the arachnoid membrane and the pia matter of the spinal cord, called the subarachnoid space. Cerebrospinal fluid also exists within this space. Because the spinal cord terminates at level L1/L2, lumbar puncture is performed from the lumbar cistern between two vertebrae at level L3/L4, or L4/L5, where there is no risk of accidental injury to the spinal cord, when a sample of CSF is needed for clinical purposes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 19 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which among the following are paired venous sinuses: Superior Petrosal Sinus Inferior petrosal sinus Superior sagittal sinus Transverse sinus Select the correct answer from the given below code:", "options": [{"label": "A", "text": "2,3,4", "correct": false}, {"label": "B", "text": "1,3,4", "correct": false}, {"label": "C", "text": "1,2,4", "correct": true}, {"label": "D", "text": "1,2,3", "correct": false}], "correct_answer": "C. 1,2,4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,2,4 There are 23 venous sinuses, of which 8 are paired, and 7 are unpaired. Paired Venous Sinuses There is one sinus each on the right and left side. Cavernous sinus Superior petrosal sinus Inferior petrosal sinus Transverse sinus Sigmoid sinus Sphenoparietal sinus Petrosquamous sinus Middle meningeal sinus/veins Unpaired Venous Sinuses These are median in position Superior sagittal sinus Inferior sagittal sinus Straight sinus Occipital sinus Anterior intercavernous sinus Posterior intercavernous sinus Basilar plexus of veins</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which is a direct content of cavernous sinus?", "options": [{"label": "A", "text": "The ophthalmic division of trigeminal vein", "correct": false}, {"label": "B", "text": "Trochlear nerve", "correct": false}, {"label": "C", "text": "Abducent nerve", "correct": true}, {"label": "D", "text": "Oculomotor nerve", "correct": false}], "correct_answer": "C. Abducent nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Abducent nerve Structures outside the cavernous sinus Superiorly: Optic tract, optic chiasma, olfactory tract, internal carotid artery, and anterior perforated substance Inferiorly: Foramen lacerum and the junction of the body and greater wing of the sphenoid bone. Medially: Hypophysis cerebri and sphenoidal air sinus. Laterally: Temporal lobe with uncus. Below laterally: Mandibular nerve Anteriorly: Superior orbital fissure and the apex of the orbit. Posteriorly: Apex of the petrous temporal and the crus cerebri of the midbrain. Structures within the lateral wall of the cavernous sinus, from above downwards: Oculomotor nerve: In the anterior part of the sinus, it divides into superior and inferior divisions which leave the sinus by passing through the superior orbital fissure. Trochlear nerve: In the anterior part of the sinus, it crosses superficial to the oculomotor nerve and enters the orbit through the superior orbital fissure. Ophthalmic nerve: In the anterior part of the sinus, it divides into the lacrimal, frontal, and nasociliary nerves. Maxillary nerve: It leaves the sinus by passing through the foramen rotundum on its way to the pterygopalatine fossa. Greg’s 41st Ed update: the maxillary nerve is not in lateral relation to the cavernous sinus. Trigeminal ganglion: The ganglion and its dural cave may project into the posterior part of the lateral wall of the sinus. Structures passing through the medial aspect of the cavernous sinus: An internal carotid artery with the venous and sympathetic plexus around it. Abducent nerve, inferolateral to the internal carotid artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following are the tributaries of the cavernous sinus? Superficial middle cerebral vein Superior petrosal sinus Inferior ophthalmic vein The central vein of the retina Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,2,3,4", "correct": false}, {"label": "B", "text": "1,3,4", "correct": true}, {"label": "C", "text": "1,2,3", "correct": false}, {"label": "D", "text": "1,4", "correct": false}], "correct_answer": "B. 1,3,4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,3,4 The superior petrosal sinus is not a tributary to the cavernous sinus. It drains the cavernous sinus into the transverse sinus. Tributaries of the Cavernous Sinus: The cavernous sinus receives blood from the orbit, meninges, and brain. From the orbit: The superior ophthalmic vein. A branch of the inferior ophthalmic vein or sometimes the vein itself. The central vein of the retina may drain either into the superior ophthalmic vein or the cavernous sinus. From the brain: Superficial middle cerebral vein. Inferior cerebral veins from the temporal lobe. From the meninges Sphenoparietal sinus. The frontal trunk of the middle meningeal vein may drain either into the pterygoid plexus through the foramen ovale or into the sphenoparietal or cavernous sinus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The central area of the face is called the dangerous area of the face because:", "options": [{"label": "A", "text": "Infection in this area causes cavernous sinus thrombosis", "correct": true}, {"label": "B", "text": "The area is liable to the formation of tumor", "correct": false}, {"label": "C", "text": "The area is directly connected to an ear", "correct": false}, {"label": "D", "text": "Infection directly reaches to meninges", "correct": false}], "correct_answer": "A. Infection in this area causes cavernous sinus thrombosis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Infection in this area causes cavernous sinus thrombosis The facial vein communicates with the cavernous sinus through the superior ophthalmic vein and deep facial vein. Hence, infection from the central area (between the lower part of nose and the upper part of the lip - a dangerous area) spreads to the cavernous sinus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All the following are true about cavernous sinus thrombosis, except: Spreads through ethmoidal sinus Marked edema of eyelids Loss of jaw jerk The infection spreads to cavernous sinus from dangerous area of the face via a superior ophthalmic vein Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,2", "correct": false}, {"label": "B", "text": "2,4", "correct": false}, {"label": "C", "text": "3", "correct": true}, {"label": "D", "text": "1", "correct": false}], "correct_answer": "C. 3", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>3 Loss of jaw jerk Routes of spread From the infection of the sphenoid sinus, ethmoid sinus, and frontal sinus Through facial veins draining dangerous areas of the face via a superior ophthalmic vein and angular vein Clinical features of cavernous sinus thrombosis Headache Involvement of III, IV & VI cranial nerves Papilledema - an increase of intra-cranial tension Loss of vision – Involvement of optic nerve Proptosis - protrusion of the eyeball Ophthalmoplegia - paralysis of eyeball muscles Chemosis- swelling of the conjunctiva</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Choose the incorrect statement regarding the marked structures in the given image:", "options": [{"label": "A", "text": "A continues as left transverse sinus", "correct": true}, {"label": "B", "text": "B is formed by Basal vein of the Rosenthal", "correct": false}, {"label": "C", "text": "C and D are present in the meningeal layer of dura mater", "correct": false}, {"label": "D", "text": "All marked sinuses are unpaired sinuses", "correct": false}], "correct_answer": "A. A continues as left transverse sinus", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392481611-QTDA019006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A continues as left transverse sinus A is the superior sagittal sinus, which via confluence, drains to the right transverse sinus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. B is Vein of Galen formed by basal vein of Rosenthal and internal cerebral vein Option: C. C and D are straight & inferior sagittal sinus respectively and are present in the meningeal layer of duramater only</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All the given options regarding marked structure are correct EXCEPT:", "options": [{"label": "A", "text": "A is drainage channel of cavernous sinus", "correct": false}, {"label": "B", "text": "B is sphenoparietal sinus", "correct": false}, {"label": "C", "text": "C is an inferior cerebral vein that drains into the cavernous sinus", "correct": true}, {"label": "D", "text": "D drains cavernous sinus into the transverse sinus", "correct": false}], "correct_answer": "C. C is an inferior cerebral vein that drains into the cavernous sinus", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392481612-QTDA019007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C is an inferior cerebral vein that drains into the cavernous sinus A is inferior petrosal sinus, drains cavernous sinus into sigmoid sinus, and forms IJV B is sphenoparietal sinus (incoming channel of cavernous sinus) C is middle meningeal vein (incoming channel of cavernous sinus) D is superior petrosal sinus, which drains cavernous sinus into the transverse sinus</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Anterior ethmoidal nerve supplies which of the following: Maxillary Sinus Internal nasal cavity Dura mater in the anterior cranial fossa Ethmoidal cells Select the correct answer from the given below code:", "options": [{"label": "A", "text": "2,3,4", "correct": true}, {"label": "B", "text": "1,,2", "correct": false}, {"label": "C", "text": "2,4", "correct": false}, {"label": "D", "text": "1,2,3,4", "correct": false}], "correct_answer": "A. 2,3,4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2,3,4 Nerve Supply of Dura mater The dura of the vault has only a few sensory nerves derived mostly from the ophthalmic division of the trigeminal nerve. 2. The dura of the floor has a rich nerve supply and is quite sensitive to pain. A. The anterior cranial fossa is supplied mostly by the anterior ethmoidal nerve and partly by the maxillary nerve. B. The middle cranial fossa is supplied by the maxillary nerve in its anterior half, and by branches of the mandibular nerve, and trigeminal ganglion in its posterior half. C. The posterior cranial fossa is supplied chiefly by recurrent branches from the first, second, and third cervical spinal nerves and partly by meningeal branches of the ninth and tenth cranial nerves. Ethmoidal Sinuses The anterior ethmoidal sinus is made up of 1 to 11 air cells, and opens into the anterior part of the hiatus semilunaris of the nose. It is supplied by the anterior ethmoidal nerve and vessels.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The arachnoid villi responsible for cerebrospinal fluid absorption protrude mainly in the:", "options": [{"label": "A", "text": "Superior Sagittal Sinus", "correct": true}, {"label": "B", "text": "Inferior sagittal sinus", "correct": false}, {"label": "C", "text": "Straight sinus", "correct": false}, {"label": "D", "text": "Transverse sinus", "correct": false}], "correct_answer": "A. Superior Sagittal Sinus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior Sagittal Sinus CSF is gradually reabsorbed into the blood through fingerlike projections into the dural venous sinuses = arachnoid granulations The nodular white excresences seen here over the cerebral hemispheres at the vertex on both sides of the central fissure with falx cerebri of the brain are the arachnoid granulations. This is where the cerebrospinal fluid produced in the choroid plexuses of the ventricles and which has circulated out of the foramina of Magendie and Luschka and into the subarachnoid space is reabsorbed.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following supply the dura mater, except:", "options": [{"label": "A", "text": "Anterior Ethmoidal", "correct": false}, {"label": "B", "text": "Posterior ethmoidal", "correct": false}, {"label": "C", "text": "Auriculotemporal", "correct": true}, {"label": "D", "text": "Mandibular", "correct": false}], "correct_answer": "C. Auriculotemporal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Auriculotemporal The auriculotemporal nerve supplies the parotid gland and skin of the cheek and ear.</p>\n<p><strong>Highyeild:</strong></p><p>Nerve Supply of the Dura Mater: Supratentorial dura is supplied by the ophthalmic nerve. Infratentorial dura (dura of the floor) has rich sensory innervation (hence very sensitive to pain). It is supplied by the following nerves: 1. In the anterior cranial fossa: by the anterior and posterior ethmoidal nerves (and receives some twigs from the maxillary nerve). 2. In the middle cranial fossa: by the meningeal branch of the maxillary nerve (in the anterior part) and the meningeal branch of the mandibular nerve (nervus spinosus) in the posterior part. 3. In the posterior cranial fossa: by the meningeal branches of the vagus and hypoglossal nerves. These are the C1 and C2 fibres carried by the cranial nerves. The dura mater around the foramen magnum is directly supplied by the C2 and C3 cervical nerves.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following true or false options about cranial dura mater is correct? It has an endosteal layer and a meningeal layer It is supplied by 5th cranial nerve It is the outermost meningeal layer Venous sinuses present inner to meningeal layer Select the correct answer from the given below code:", "options": [{"label": "A", "text": "TTFF", "correct": false}, {"label": "B", "text": "TFTF", "correct": false}, {"label": "C", "text": "TFFF", "correct": false}, {"label": "D", "text": "TTTF", "correct": true}], "correct_answer": "D. TTTF", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>TTTF Coronal sections through the posterior cranial fossa showing folds of dura mater and the venous sinuses enclosed in them: (a) Section through the tentorial notch (anterior part of the fossa); (b) Section through the middle part of the fossa; (c) Section through the posteriormost part</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Blood supply of dura mater is by all of the following except?", "options": [{"label": "A", "text": "Meningeal branch of the internal carotid artery in posterior cranial fossa", "correct": true}, {"label": "B", "text": "Accessory meningeal artery", "correct": false}, {"label": "C", "text": "Meningeal branch of an anterior and posterior ethmoidal artery", "correct": false}, {"label": "D", "text": "Middle meningeal artery", "correct": false}], "correct_answer": "A. Meningeal branch of the internal carotid artery in posterior cranial fossa", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Meningeal branch of the internal carotid artery in posterior cranial fossa Blood Supply of Dura Mater: The outer layer is richly vascular. The inner meningeal layer is more fibrous and requires little blood supply. The vault or supratentorial space is supplied by the middle meningeal artery. The anterior cranial fossa and the dural lining are supplied by meningeal branches of the anterior ethmoidal, posterior ethmoidal, and ophthalmic arteries. The middle cranial fossa is supplied by the middle meningeal, accessory meningeal, internal carotid arteries; and meningeal branches of the ascending pharyngeal artery. The posterior cranial fossa is supplied by meningeal branches of the vertebral, occipital, and ascending pharyngeal arteries.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 22 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A male patient of 32 years was admitted to the emergency department, with a lot of injuries seen on his face and head region with bleeding. His relatives told to the doctor that he had been injured in a roadside accident. On examination, the doctor found severe bleeding from the nose along with some watery fluid. After 3 days, on examination, it was found that the patient is having unilateral anosmia. Which cranial nerve is damaged in this case and what is the reason for the anosmia?", "options": [{"label": "A", "text": "Optic nerve; anosmia due to damage to the orbicularis oculi in the accident", "correct": false}, {"label": "B", "text": "Olfactory nerve; anosmia due to damaged olfactory nerve rootlets", "correct": true}, {"label": "C", "text": "Olfactory nerve; anosmia due to damaged nasal septum", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "B. Olfactory nerve; anosmia due to damaged olfactory nerve rootlets", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Olfactory nerve; anosmia due to damaged olfactory nerve rootlets The olfactory nerve is damaged; anosmia due to injury to the olfactory nerve rootlet is because of fracture of the cribriform plate of ethmoid from which it is passing. As the patient has anosmia which is the loss of sense of smell. It may be temporary or permanent. And, we know that the cranial nerve first which is the olfactory nerve is responsible for carrying a sense of smell. Damage to the olfactory nerve can lead to anosmia-like conditions. Damage may be at any part of the olfactory pathway. But the patient has bleeding from the nose as well as CSF flowing out with the blood that indicated the fracture of the cribriform plate of ethmoid that's why the CSF can easily flow from the anterior cranial cavity to the nasal openings.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect Because the optic nerve is not related to the sense of smell, which is damaged in the patient. The main function of the optic nerve is in the vision process. Orbicularis oculi is the muscle of the eyelids around the orbital openings. Option: C. Incorrect The olfactory nerve is responsible for the sense of smell, which is lost in the patient, so yes there is damage to the olfactory nerve injury to the nasal septum can cause bleeding from the nose, but nasal septum injuries never cause CSF flowing out through the nose CSF can only be found in nasal bleeding when there is an injury to the anterior cranial fossa or cribriform plate of the ethmoid.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 60 years old woman is seen as an outpatient, she complains that she has developed double vision. She has a head injury 1 week ago, and after that injury, she is having some hearing impairment and some abnormal facial expressions. A complete physical examination has been performed and it shows that she is having medially turned her right eye at rest and she is unable to turn in laterally, but her visual acuity is normal for near and distant objects. What is the site of injury and the main nerve damage responsible for these symptoms?", "options": [{"label": "A", "text": "Optic canal; optic nerve", "correct": false}, {"label": "B", "text": "Lower pons at the pontomedullary junction; abducent nerve", "correct": true}, {"label": "C", "text": "Upper pons; abducent nerve", "correct": false}, {"label": "D", "text": "All of the above", "correct": false}], "correct_answer": "B. Lower pons at the pontomedullary junction; abducent nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lower pons at the pontomedullary junction; abducent nerve The site of injury is at a lower pons level at the pontomedullary junction, as because the abducent nerve nuclei are present here, which is damaged in this case. Also, other symptoms like abnormal facial expressions and hearing loss are due to damage to the 7 th nerve nuclei and 8 th nerve nuclei damage which are also present there at the pontomedullary junction.</p>\n<p><strong>Highyeild:</strong></p><p>Abducent nerve damage leads to a medial squint of her right eye, diplopia and inability to move her right eye laterally. Due to paralysis of the lateral rectus muscle which is responsible for lateral movement of the eye, and is supplied by the abducent nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect As the patient is having no problem with near or distant object vision, her visual acuity is found to be normal. If the optic nerve is damaged that leads to blindness. The optic canal is the canal by which the optic nerve and ophthalmic artery are transmitted in the orbit. It is present in the lesser wing of the sphenoid bone. Option: C. Incorrect The abducent nerve is damaged here, but the abducent nerve took its origin from its nuclei which are present in the lower pons at the pontomedullary junction, not in the upper pons. Option: D. Incorrect As all of the above-given statements are not true,</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Patients having abducent nerve nuclei injury due to injury to the pontomedullary junction at lower pons are usually presented in the clinics in having problems such as inability to move their affected side eye laterally, even at rest that eye is turned medially only, as due to paralysis of the lateral rectus muscle. What are the functional nuclei that are damaged in this case?", "options": [{"label": "A", "text": "Special somatic afferent", "correct": false}, {"label": "B", "text": "General somatic afferent +general somatic efferent", "correct": true}, {"label": "C", "text": "General visceral efferent", "correct": false}, {"label": "D", "text": "Special visceral efferent", "correct": false}], "correct_answer": "B. General somatic afferent +general somatic efferent", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>General somatic afferent +general somatic efferent General somatic afferent nuclei fibres are there in the abducent nerve, for proprioceptive impulses from lateral rectus muscle to mesencephalic nuclei of 5 th nerve. General somatic efferent fibres are present in the 6 th nerve for lateral movement of the eyeball through the lateral rectus muscle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect special somatic afferent nuclei are related to sight; olfaction and hearing function Optic; olfactory and vestibulocochlear nerve is related to these function and the special somatic afferent nuclei. Option: C. Incorrect General visceral efferent nuclei are related to preganglionic neurons that relay in peripheral autonomic ganglion This column is found in 3; 7 ;9 and 10th cranial nerve Option: D. Incorrect Special visceral efferent nuclei supply striated muscles derived from branchial arches. It is related to cranial nerves like the 7th,5th,9th and 10th.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 54 years old male patient visited his physician's clinic, he has a known history of cerebrovascular problems. He complained that he had trouble reading the paper, the print started to tilt and began to see double. On examination the doctor found that he has weakness of movement of the right eye both downward and laterally only, the rest of the movements of the eyeball is normal. Which nerve is involved in this case and where is its nuclei located?", "options": [{"label": "A", "text": "Trochlear nerve; trochlear nuclei in the midbrain at the level of the inferior colliculus", "correct": true}, {"label": "B", "text": "Abducent nerve; abducent nerve nuclei in the upper pons", "correct": false}, {"label": "C", "text": "Facial nerve; facial nerve nuclei in the lower pons region", "correct": false}, {"label": "D", "text": "Trochlear nerve; trochlear nuclei in the midbrain at the superior colliculus level", "correct": false}], "correct_answer": "A. Trochlear nerve; trochlear nuclei in the midbrain at the level of the inferior colliculus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Trochlear nerve; trochlear nuclei in the midbrain at the level of the inferior colliculus The trochlear nerve is damaged in this case, which leads to the paralysis of the superior oblique muscle. Due to paralysis of the superior oblique muscle, he is facing difficulty in the downward and lateral movement of the eyeball, as these functions are performed by the superior oblique muscle. Trochlear nerve nuclei are present in the midbrain at the level of the inferior colliculus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Incorrect The abducent nerve supplies the lateral rectus muscle of the The lateral rectus muscle is responsible for the abduction of the eyeball only, it does not cause depression of the eyeball. But the superior oblique muscle causes depression as well as the abduction of the eyeball. So in this patient superior oblique is damaged, as the symptoms indicate. Abducent nerve nuclei are present in lower pons at the pontomedullary junction. Option: C. Incorrect As facial nerve does not supply the muscles of the eyeball and it is not even related to eyeball movement. Facial nerve nuclei are present in lower pons at the pontomedullary junction. Option: D. Incorrect As the trochlear nerve is damaged in this case, there is paralysis of the superior oblique muscle. So the patient has problems with abduction and depression movement of the eyeball. But trochlear nerve nuclei are present in the midbrain at the level of the inferior colliculus, not at the superior colliculus level.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 40-year-old male patient arrived in your clinic, with complaints of diplopia and ptosis. On examination, you find that he is having dilated pupils, loss of accommodation and loss of pupillary light reflex. No signs of blindness are found. Which nerve is involved in this case and what is the reason for the loss of pupillary and accommodation reflex in this case?", "options": [{"label": "A", "text": "Oculomotor nerve; loss of pupillary reflex due to damaged parasympathetic fibres of Edinger Westphal nucleus.", "correct": true}, {"label": "B", "text": "Optic nerve; lesion of the optic tract", "correct": false}, {"label": "C", "text": "Facial nerve; damage to Edinger Westphal nucleus", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Oculomotor nerve; loss of pupillary reflex due to damaged parasympathetic fibres of Edinger Westphal nucleus.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Oculomotor nerve; loss of pupillary reflex due to damaged parasympathetic fibres of Edinger Westphal nucleus. The oculomotor nerve is damaged in this case, as paralysis of the oculomotor nerve leads to conditions like ptosis due to paralysis of the voluntary part of the levator palpebrae superioris muscle. Pupillary light reflex is absent in the affected eye and dilation of the pupil is found because of paralysis of parasympathetic fibres from the Edinger Westphal nucleus which travels along the oculomotor nerve, these supply sphincter pupillae muscle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Is incorrect Optic nerve damage leads to complete blindness, it is not found in this case. And lesion of the optic tract leads to homonymous hemianopia on the opposite side. Option: C. Incorrect Facial nerves do not supply any structure within the eyeball So it is not related to ptosis and diplopia found in this case. It supplies the facial muscles that maintain facial expression. Edinger Westphal nucleus is closely related to the oculomotor nerve nucleus in the midbrain. It supplies parasympathetic fibres to sphincter pupillae and ciliaris muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient arrived in the outpatient department, he has a complaint of defective speech due to sluggishly movement of the tongue. On examination, it was found that the tongue is deviated to the right side. The doctor diagnosed him with 12th nerve paralysis. What are the functional nuclei columns which are damaged in this case?", "options": [{"label": "A", "text": "Special visceral efferent", "correct": false}, {"label": "B", "text": "Special somatic afferent", "correct": false}, {"label": "C", "text": "General somatic efferent and general somatic afferent", "correct": true}, {"label": "D", "text": "All of the above", "correct": false}], "correct_answer": "C. General somatic efferent and general somatic afferent", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>General somatic efferent and general somatic afferent The hypoglossal nerve supplies the muscle of the tongue, whose unilateral paralysis results in deviation of the tongue to the same side It has a general somatic efferent column whose function is related to the movements of the tongue and general somatic afferent column as it carries proprioceptive fibres from the tongue.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect As a special visceral efferent column is related to the 5;7;9 and 10 the cranial nerve and its function is to supply muscles of branchial arches Option: B. Incorrect A special somatic afferent column is related to the function of vision; olfaction and hearing. the optic, olfactory and vestibulocochlear nerve is the nerve having this column Option: D. Incorrect The optic nerve has visual functions. And olfactory nerve has olfaction functions. So they are not having any function related to tongue muscles.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A male patient of age 32 years old, on examination is found to have impairment of appreciation of pain and temperature of the face only. The doctor diagnosed this case as trigeminal nerve damage. Which nucleus of the trigeminal nerve is possibly damaged in this case?", "options": [{"label": "A", "text": "Spinal nucleus of the trigeminal nerve", "correct": true}, {"label": "B", "text": "The principal sensory nucleus of the trigeminal nerve", "correct": false}, {"label": "C", "text": "The mesencephalic nucleus of the trigeminal nerve", "correct": false}, {"label": "D", "text": "Motor nucleus of the trigeminal nerve", "correct": false}], "correct_answer": "A. Spinal nucleus of the trigeminal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spinal nucleus of the trigeminal nerve The trigeminal nerve sub serves sensation from the face and neighbouring areas. It also innervates the muscles of mastication The spinal nucleus of the trigeminal nerve is damaged in this case. Fibres conveying pain and temperature sensations from most of the face area relay here. So, if it is damaged, pain and temperature sensations of the face will be lost.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Incorrect Principle sensory nuclei of the trigeminal nerve is having the fibres of touch and pressure from the face area. If they are damaged, touch and pressure sensations of the face are Option: C. Incorrect Mesencephalic nuclei of the trigeminal nerve receive proprioceptive impulses from muscles of mastication. Option: D. Incorrect The motor nucleus of the trigeminal nerve supplies the muscles of a first branchial arch. If they are injured that leads to paralysis of muscles of mastication.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A male patient of 40 years old is having a complaint of anosmia for the previous few weeks. He is also having complaints of headaches and seizures. The doctor advised me to have a CT scan of the brain. The CT scan shows an extra-axial mass, with a well-defined border and dural attachment. The doctor diagnosed it as meningioma in anterior cranial fossa. What is the cause of anosmia here?", "options": [{"label": "A", "text": "Compression of the facial nerve", "correct": false}, {"label": "B", "text": "Compression of the olfactory bulb and olfactory tract", "correct": true}, {"label": "C", "text": "Compression on the vagus nerve", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "B. Compression of the olfactory bulb and olfactory tract", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Compression of the olfactory bulb and olfactory tract Meningioma of the anterior cranial fossa may compress the olfactory bulb and olfactory tract resulting in anosmia means loss of smell sensations. As the olfactory bulbs are located in the frontal part of the anterior cranial fossa, so they are commonly damaged in meningioma of the anterior cranial fossa.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect Facial nerve nuclei are present in the lower pons region at the pontomedullary junction, it is not involved in the lesion of the anterior cranial fossa. And the facial nerve is not related to the function of smell sensations. Option: C. Incorrect The vagus nerve is present in the medulla region not in the anterior cranial fossa. So it cannot be damaged in lesions of the anterior cranial fossa and is even not related to the sense of smell.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 60-year-old lady is diagnosed as having an advanced carcinoma of the nasopharynx with neoplastic infiltrations of the posterior cranial fossa. She has a chief complaint of loss of taste sensations over the posterior 1/3rd of the tongue. The uvula is found elevated in the midline and she can shrug her shoulders by using the trapezius muscles normally. Which nerve is damaged in this case?", "options": [{"label": "A", "text": "Facial Nerve", "correct": false}, {"label": "B", "text": "Spinal accessory nerve", "correct": false}, {"label": "C", "text": "Vagus nerve", "correct": false}, {"label": "D", "text": "Glossopharyngeal nerve", "correct": true}], "correct_answer": "D. Glossopharyngeal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Glossopharyngeal nerve The glossopharyngeal nerve is present in the medulla region. It supplies the posterior 1/3rd of the tongue and sub-serves common sensations and taste sensations from there If it is damaged posterior 1/3rd of taste sensations of the tongue is lost, as found in this case</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect The facial nerve arises from the lower pons area. It is carrying the taste sensations from the anterior 2/3rd of the So if it is damaged then taste is to be lost from the anterior 2/3rd area of the Option: B. Incorrect Spinal accessory nerve supplies trapezius and sternocleidomastoid muscles If it is damaged then the patient is not able to shrug the shoulders properly, due to the paralysis of the trapezius muscle. Option: C. Incorrect The Vagus nerve supplies the muscles of the palate, pharynx and larynx and it is responsible for maintaining the palatal arches. If it is damaged uvula deviated to the opposite side</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 70-year-old male consults a physician, as he is becoming deaf. He is annoyed to find that his head size has increased, in a couple of months. He is also having complaints of headaches for the past few days. He has no other symptoms. The doctor asked him to protrude his tongue and he found the tongue protruded straight forwards. The doctor advised the patient for a CT scan after looking at the CT scan the doctor finds increased cranial bone thickness and slight compression in the brain size. What is your diagnosis for this disease and its symptoms?", "options": [{"label": "A", "text": "Paget's disease; compression of the vestibulocochlear nerve", "correct": true}, {"label": "B", "text": "Gorham stout disease; compression of the vestibulocochlear nerve", "correct": false}, {"label": "C", "text": "Paget's disease; compression of the hypoglossal nerve", "correct": false}, {"label": "D", "text": "All of the above", "correct": false}], "correct_answer": "A. Paget's disease; compression of the vestibulocochlear nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Paget's disease; compression of the vestibulocochlear nerve In Paget's disease of bones, there is an increased thickening of bone found due to new bone mass formation. As a result the thickness of the calvarium increases, which leads to compression of brain and cranial nerves which passes through small and narrower openings. Usually for vestibulocochlear nerve as it passes through the narrowing of the internal acoustic meatus. Compression of the vestibulocochlear nerve leads to hearing loss, as found here</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Incorrect The vestibulocochlear nerve is responsible for hearing function but Gorham stout disease is a vanishing bone disease with progressive bone loss found due to osteolysis this is not found in this case, even though there is a thickening of bones found here Option: C. Incorrect Hypoglossal nerves arise from the medulla, and it supplies mainly to the tongue muscle. If it is compressed, the tongue will deviate to the paralysed side. But no such deviation was found in this patient. Option: D. Is incorrect As option b and option c are incorrect, so all of the above cannot be the answer</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A female patient of 32 years old is diagnosed with syringomyelia. On physical exam examination, she is found to have no impairment of appreciation of pain and temperature of the face, but she is having an impairment of appreciation of light touch, pain and temperature sensations from the lower body parts is preserved. What are the most problem nuclei/site of damage?", "options": [{"label": "A", "text": "The lesion in the anterolateral column of the spinal cord", "correct": false}, {"label": "B", "text": "The lesion in the motor nuclei of the facial nerve", "correct": false}, {"label": "C", "text": "The lesion in the spinal nuclei of the trigeminal nerve", "correct": false}, {"label": "D", "text": "The lesion in principal sensory nuclei of the trigeminal nerve", "correct": true}], "correct_answer": "D. The lesion in principal sensory nuclei of the trigeminal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The lesion in principal sensory nuclei of the trigeminal nerve The trigeminal nerve is the largest cranial nerve. It has three branches, two of which are purely sensory and the third one is mixed. Principle sensory nucleus of the trigeminal nerve is carrying the fibres of touch and pressure sensations from the face area. If they are damaged, the patient's touch and pressure sensations in the face area will be lost</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect We know that the anterolateral column of the spinal cord carries pain, light touch and temperature sensations of lower body parts. So, if they are damaged, the pain, temperature and touch sensations are lost in the lower body, which is preserved in this case. Option: B. Incorrect As the motor nuclei of the facial nerve supply the muscles of facial expression and carry out their movements. If it is damaged facial expression of the patient will be lost. Option: C. Incorrect Because the spinal nuclei of the trigeminal nerve have fibres conveying pain and temperature sensations in the face. So if it is damaged pain and temperature sensation of the face are lost</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient is admitted to the emergency department having symptoms like headache, nausea and vomiting. The doctor advised the patient to get MRI done. The MRI scan shows neoplastic growth in the medulla region. She is diagnosed with advanced-stage carcinoma of the medulla oblongata. All of the given signs and symptoms are found in the patient except?", "options": [{"label": "A", "text": "Loss of taste sensation from posterior 2/3rd of tongue", "correct": false}, {"label": "B", "text": "Blindness", "correct": true}, {"label": "C", "text": "Complete paralysis of the tongue", "correct": false}, {"label": "D", "text": "Weakness in shrugging the shoulders", "correct": false}], "correct_answer": "B. Blindness", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Blindness Blindness is not found in the case of carcinoma of the medulla as blindness of the eye is found in cases of damage to the optic nerve is found in the anterior cranial region, not in the medulla so medullary carcinoma does not affect the optic nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect Because the glossopharyngeal nerve is attached to the upper part of the posterolateral sulcus of the medulla, it is damaged in cases of medullary carcinoma. Damage to this nerve leads to loss of taste sensation from the posterior 1/3rd of the Option: C. Incorrect Complete paralysis of the tongue is seen in cases of bilateral paralysis of the 12th nerve. The hypoglossal nerve is attached to the anterolateral sulcus of the medulla, so it is affected in cases of medullary carcinoma it supplies to the muscles of the tongue. Option: D. Incorrect Weakness in shrugging of the shoulders is commonly seen in cases of damage to the cranial part of the accessory nerve cranial root emerges from the posterolateral sulcus of the medulla it is also commonly damaged in cases of carcinoma of the medulla.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A doctor on examination of a male patient of 40 years old found drooping of the shoulder and an inability to turn his chin to the opposite side. According to you, what is the structure damaged in this case?", "options": [{"label": "A", "text": "Lesion to the spinal root of the accessory nerve", "correct": true}, {"label": "B", "text": "Lesion to the glossopharyngeal nerve", "correct": false}, {"label": "C", "text": "Lesion to the upper lateral cutaneous nerve of the arm", "correct": false}, {"label": "D", "text": "Lesion to supraclavicular nerve", "correct": false}], "correct_answer": "A. Lesion to the spinal root of the accessory nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lesion to the spinal root of the accessory nerve The spinal part of the accessory nerve arises from the spinal nucleus of the accessory nerve which is situated in the c1-c5 segment of the spinal cord. It supplies to the sternocleidomastoid and trapezius muscles, both of which are important for movements like shrugging of the shoulder and moving the chin to the opposite side. So lesion to the spinal root of the accessory nerve causes drooping of the shoulder and the inability to turn the chin to the opposite side.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Incorrect The glossopharyngeal nerve is carrying the taste sensation from the posterior 1/3rd of the tongue and if it is damaged the patient will have a loss of taste sensations from the posterior 1/3rd tongue Option: C. Incorrect The upper lateral cutaneous nerve of the arm is responsible for carrying sensory sensations from the upper lateral arm region. If it is damaged it leads to loss of sensory sensation over the upper lateral side of the arm Option: D. Incorrect The supraclavicular nerve is providing the sensory sensations from the clavicle and anteromedial shoulder If it is damaged, there is a loss of sensation from these areas.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The boy, fall from a running bus, which partially ran over him and caused injury to the base of his skull. The origin of the internal jugular vein at the jugular foramen was compromised. Which of the following cranial nerves courses through the jugular foramen?", "options": [{"label": "A", "text": "Abducens (sixth cranial) nerve", "correct": false}, {"label": "B", "text": "Facial (seventh cranial) nerve", "correct": false}, {"label": "C", "text": "Hypoglossal (twelfth cranial) nerve", "correct": false}, {"label": "D", "text": "The spinal accessory nerve (eleventh cranial) nerve", "correct": true}], "correct_answer": "D. The spinal accessory nerve (eleventh cranial) nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The spinal accessory nerve (eleventh cranial) nerve The spinal accessory (eleventh cranial) nerve takes its origins in the neck, but then runs cranially into the skull through the foramen magnum to join with its cranial component. They exist as one through the jugular foramen, along with the glossopharyngeal (ninth cranial) and vagus (tenth cranial) nerves.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The abducens (sixth cranial) nerve runs through the superior orbital fissure to reach the orbit. Option: B. The facial (seventh cranial; ) and vestibulocochlear nerves run together through the internal acoustic meatus into the temporal bone. The facial nerve exits the skull through the stylomastoid foramen. Option: C. The hypoglossal (twelfth cranial; ) nerve exits the skull through the hypoglossal canal.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Palsy of which nerve in the following Image causes the inability to produce horizontal, conjugate eye movements in one or both directions?", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": true}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "B. B", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392591710-QTDA022015IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>B Lateral gaze palsy is an inability to produce horizontal, conjugate eye movements in one or both directions. Lesions of the cranial nerve VI (abducens) nucleus in the pons cause ipsilateral, lateral gaze palsy. The given image is of Cavernous Sinus where = Oculomotor Nerve (III) = Abducent Nerve (VI) = Ophthalmic Nerve (V) = Maxillary Nerve Oculomotor nerve palsy will result in a characteristic down and out the position in the affected eye. The eye will be displaced outward \"exotropia\" and displaced downward \"hypotropia\"; outward because the lateral rectus (innervated by the sixth cranial nerve) maintains muscle tone in comparison to the paralyzed medial rectus. The eye will be displaced downward, because the superior oblique (innervated by the fourth cranial or trochlear nerve), is unantagonized by the paralyzed superior rectus, inferior rectus and inferior oblique. The affected individual will also have ptosis, drooping of the eyelid, and mydriasis (pupil dilation). In injury of the ophthalmic nerve, there is loss of corneal blink reflex. The maxillary nerve is the second branch of the trigeminal nerve, which originates embryologically from the first pharyngeal arch. Its primary function is sensory supply to the mid-third of the face. In cases of injury to the maxillary nerve, there is a loss of the sneeze reflex. This branch is the afferent path for the sneeze reflex.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Intraocular muscle supplied by Edinger Westphal nucleus is:", "options": [{"label": "A", "text": "Superior Oblique", "correct": false}, {"label": "B", "text": "Ciliary muscle", "correct": true}, {"label": "C", "text": "Lateral rectus", "correct": false}, {"label": "D", "text": "Medial rectus", "correct": false}], "correct_answer": "B. Ciliary muscle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ciliary muscle Edinger Westphal nucleus sends the Preganglionic parasympathetic fibres through oculomotor nerve to ciliary ganglion, which further supplies two smooth muscles of the eyeball: ciliary and sphincter papilla</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following sensation is not perceived by the spinal nucleus of the trigeminal nerve?", "options": [{"label": "A", "text": "Pain", "correct": false}, {"label": "B", "text": "Touch", "correct": false}, {"label": "C", "text": "Temperature", "correct": false}, {"label": "D", "text": "Proprioception", "correct": true}], "correct_answer": "D. Proprioception", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Proprioception Proprioception is the function of the Mesencephalic nucleus. General Somatic Afferent Nuclei: These are all related to the trigeminal nerve. The main or superior sensory nucleus of the trigeminal nerve lies in the upper part of the pons The spinal nucleus of the trigeminal nerve descends from the main nucleus into the medulla. The mesencephalic nucleus of the trigeminal nerve extends upwards from the main sensory nucleus into the midbrain. These nuclei receive the following fibres: Exteroceptive sensations (touch, pain, temperature) from the skin of the face, through the trigeminal nerve; and from a part of the skin of the auricle through the vagus (auricular branch) and the facial nerve. Proprioceptive sensations from muscles of mastication reach the mesencephalic nucleus through the trigeminal nerve. The nucleus is also believed to receive proprioceptive fibres from the ocular, facial and lingual muscles, teeth and temporomandibular joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All the following statements about the vagus nerve are true except?", "options": [{"label": "A", "text": "Supplies heart and lung", "correct": false}, {"label": "B", "text": "Carries postganglionic parasympathetic fibres", "correct": true}, {"label": "C", "text": "Innervates up to the right two-thirds of the transverse colon", "correct": false}, {"label": "D", "text": "Stimulates peristalsis and relaxes sphincters", "correct": false}], "correct_answer": "B. Carries postganglionic parasympathetic fibres", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Carries postganglionic parasympathetic fibres Special Visceral Efferent/Branchial Efferent Nuclei These nuclei supply striated muscle derived from the branchial arches. The motor nucleus of the trigeminal nerve lies in the upper part of the pons. It supplies the muscles of mastication through the mandibular nerve. The nucleus of the facial nerve lies in the lower part of the pons. It supplies the various muscles innervated by the facial nerve. The nucleus ambiguity lies in the medulla. It forms an elongated column lying in both the open and closed parts of the medulla. It supplies a. The stylopharyngeus muscle through the glossopharyngeal nerve; and b. The muscles of the soft palate, the pharynx and the larynx through the vagus nerve and the cranial part of the accessory nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Special visceral Efferent fibres supply:", "options": [{"label": "A", "text": "Striated muscles of a limb", "correct": false}, {"label": "B", "text": "Muscles of mastication", "correct": true}, {"label": "C", "text": "Extrinsic muscles of the limb", "correct": false}, {"label": "D", "text": "The musculature of the iris", "correct": false}], "correct_answer": "B. Muscles of mastication", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Muscles of mastication SVE includes the nucleus of the nerve supplying pharyngeal arches- V3, VII, IX, X, XI V3 nerve supplies muscles of mastication. Special Visceral Efferent/Branchial Efferent Nuclei These nuclei supply striated muscle derived from the branchial arches. The motor nucleus of the trigeminal nerve lies in the upper part of the pons. It supplies the muscles of mastication through the mandibular nerve. The nucleus of the facial nerve lies in the lower part of the pons. It supplies the various muscles innervated by the facial nerve. The nucleus ambiguity lies in the medulla. It forms an elongated column lying in both the open and closed parts of the medulla. It supplies The stylopharyngeus muscle through the glossopharyngeal nerve; and The muscles of the soft palate, the pharynx and the larynx through the vagus nerve and the cranial part of the accessory nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The nucleus in the brain common to IX, X, and XI cranial nerves:", "options": [{"label": "A", "text": "Nucleus Solitaries", "correct": false}, {"label": "B", "text": "Nucleus ambiguous", "correct": true}, {"label": "C", "text": "Dentate nucleus", "correct": false}, {"label": "D", "text": "Red nucleus", "correct": false}], "correct_answer": "B. Nucleus ambiguous", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Nucleus ambiguous Explanation: NA is present in SVE column and nerves arising from it supply muscles of palate, pharynx and larynx.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 30 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A male patient of 32 years was admitted to the emergency department, with a lot of injuries seen on his face and head region with bleeding. His relatives told the doctor that he had been injured in a roadside accident. On examination, the doctor found severe bleeding from the nose along with some watery fluid. After 3 days, on examination, it was found that the patient is having unilateral anosmia. Which cranial nerve is damaged in this case and what is the reason for the anosmia?", "options": [{"label": "A", "text": "Optic nerve; anosmia due to damage to the orbicularis oculi in the accident", "correct": false}, {"label": "B", "text": "Olfactory nerve; anosmia due to damaged olfactory nerve rootlets", "correct": true}, {"label": "C", "text": "Olfactory nerve; anosmia due to damaged nasal septum", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "B. Olfactory nerve; anosmia due to damaged olfactory nerve rootlets", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Olfactory nerve; anosmia due to damaged olfactory nerve rootlets The olfactory nerve is damaged; anosmia due to injury to the olfactory nerve rootlet is because of fracture of the cribriform plate of ethmoid from which it is passing. As the patient has anosmia which is a loss of sense of smell. It may be temporary or permanent. And, we know that the cranial nerve first, that is olfactory nerve, is responsible for carrying a sense of smell.</p>\n<p><strong>Highyeild:</strong></p><p>Damage to the olfactory nerve can lead to anosmia-like conditions. Damage may be at any part of the olfactory pathway. But the patient has bleeding from the nose as well as CSF flowing out with the blood that indicated the fracture of the cribriform plate of ethmoid that's why the CSF can easily flow from the anterior cranial cavity to the nasal openings.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect Because the optic nerve is not related to the sense of smell, which is damaged in the patient. The main function of the optic nerve is in the vision process. Orbicularis oculi is the muscle of the eyelids around the orbital openings. Option: C. Incorrect The olfactory nerve is responsible for a sense of smell, which is lost in the patient, so yes there is damage to the olfactory nerve injury to the nasal septum can cause bleeding from the nose, but nasal septum injuries never cause CSF flowing out through the nose CSF can only be found in nasal bleeding when there is an injury to the anterior cranial fossa or cribriform plate of the Option D. None of the above The olfactory nerve is damaged in the above case, as anosmia due to injury to the olfactory nerve rootlet because of fracture of the cribriform plate of ethmoid from which it is passing.</p>\n<p><strong>Extraedge:</strong></p><p>The olfactory nerve is the first cranial nerve and is instrumental in our sense of smell. The olfactory nerve contains only afferent sensory nerve fibres and, like all cranial nerves, is paired.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 60 years old woman is seen as an outpatient, she complains that she has developed double vision. She had a head injury 1 week ago, and after that injury, she is having some hearing impairment. The doctor found that she does have some abnormal facial expressions also. A complete physical examination has been performed and it shows that she is having medially turned her right eye at rest and she is unable to turn in laterally, but her visual acuity is normal for near and distant objects. What is the site of injury and the main nerve damage responsible for these symptoms?", "options": [{"label": "A", "text": "Optic canal; optic nerve", "correct": false}, {"label": "B", "text": "Lower pons at the pontomedullary junction; abducens nerve", "correct": true}, {"label": "C", "text": "Upper pons; abducens nerve", "correct": false}, {"label": "D", "text": "All of the above", "correct": false}], "correct_answer": "B. Lower pons at the pontomedullary junction; abducens nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lower pons at the pontomedullary junction; abducens nerve The site of injury is at a lower pons level at the pontomedullary junction, as because the abducens nerve nuclei are present here, which is damaged in this case. Also, other symptoms like abnormal facial expressions and hearing loss are due to damage to the 7 th nerve nuclei and 8 th nerve nuclei damage which are also present there at the pontomedullary junction.</p>\n<p><strong>Highyeild:</strong></p><p>Abducens nerve damage leads to a medial squint of her right eye, diplopia and inability to move her right eye laterally. Due to paralysis of the lateral rectus muscle which is responsible for lateral movement of the eye, it is supplied by the abducens nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect As the patient is having no problem with near or distant object vision, her visual acuity is found to be normal. If the optic nerve is damaged that leads to blindness. The optic canal is the canal by which the optic nerve and ophthalmic artery are transmitted in orbit. It is present in the lesser wing of the sphenoid bone. Option: C. Incorrect The Abducens nerve is damaged here, but the Abducens nerve took its origin from its nuclei which are present in the lower pons at the pontomedullary junction, not in the upper pons. Option: D. Incorrect All of the above-given statements are not true.</p>\n<p><strong>Extraedge:</strong></p><p>The facial nerve , also known as the seventh cranial nerve , cranial nerve VII , or simply CN VII , is a cranial nerve that emerges from the pons of the brainstem, controls the muscles of facial expression, and functions in the conveyance of taste sensations from the anterior two-thirds of the tongue. The nerve typically travels from the pons through the facial canal in the temporal bone and exits the skull at the stylomastoid foramen. It arises from the brainstem from an area posterior to the cranial nerve VI (abducens nerve) and anterior to the cranial nerve VIII (vestibulocochlear nerve). The facial nerve also supplies preganglionic parasympathetic fibres to several head and neck ganglia. The facial and intermediate nerves can be collectively referred to as the nervus intermediofacialis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Patients having abducens nerve nuclei injury due to injury to the pontomedullary junction at lower pons are usually presented in the clinics in having problems such as inability to move their affected side eye laterally, even at rest that eye is turned medially only, as due to paralysis of the lateral rectus muscle. What are the functional nuclei that are damaged in this case?", "options": [{"label": "A", "text": "Special somatic afferent", "correct": false}, {"label": "B", "text": "General somatic afferent +general somatic efferent", "correct": true}, {"label": "C", "text": "General visceral efferent", "correct": false}, {"label": "D", "text": "Special visceral efferent", "correct": false}], "correct_answer": "B. General somatic afferent +general somatic efferent", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>General somatic afferent +general somatic efferent General somatic afferent nuclei fibres are there in the abducens nerve, for proprioceptive impulses from the lateral rectus muscle to the mesencephalic nucleus of the 5 th General somatic efferent fibres are present in the 6 th nerve for lateral movement of the eyeball through the lateral rectus muscle.</p>\n<p><strong>Highyeild:</strong></p><p>The Abducens nerve is the 6th cranial nerve. It is purely motor and supplies only one muscle—the lateral rectus of the eyeball. Origin, course, and distribution of the abducens nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect special somatic afferent nuclei are related to sight; olfaction and hearing function Optic; olfactory and vestibulocochlear nerve is related to these functions and the special somatic afferent nuclei. Option: C. Incorrect General visceral efferent nuclei are related to preganglionic neurons that rely on peripheral autonomic ganglion This column is found in 3; 7 ;9 and 10th cranial nerve Option: D. Incorrect Special visceral efferent nuclei supply striated muscles derived from branchial arches. It is related to cranial nerves like the 7th,5th,9th and 10th.</p>\n<p><strong>Extraedge:</strong></p><p>Functional Components and Nuclei General somatic efferent fibres. They arise from the abducens nucleus in the pons and supply the lateral rectus muscle of the eyeball. General somatic afferent fibres. They carry proprioceptive sensations from the lateral rectus and terminate in the mesencephalic nucleus of the trigeminal nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 54 years old male patient visited his physician’s clinic, he has a known history of cerebrovascular problems. He complained that he had trouble reading the paper, the print started to tilt and began to see double. On examination, the doctor found that he has weakness of movement of the right eye both downward and laterally only, the rest of all movements of the eyeball are normal. Which nerve is involved in this case and where is its nucleus located?", "options": [{"label": "A", "text": "Trochlear nerve; trochlear nuclei in the midbrain at the level of the inferior colliculus", "correct": true}, {"label": "B", "text": "Abducens nerve; abducens nerve nuclei in the upper pons", "correct": false}, {"label": "C", "text": "Facial nerve; facial nerve nuclei in the lower pons region", "correct": false}, {"label": "D", "text": "Trochlear nerve; trochlear nuclei in the midbrain at superior colliculus level", "correct": false}], "correct_answer": "A. Trochlear nerve; trochlear nuclei in the midbrain at the level of the inferior colliculus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Trochlear nerve; trochlear nuclei in the midbrain at the level of the inferior colliculus The trochlear nerve is damaged in this case, which leads to the paralysis of the superior oblique muscle. Due to paralysis of the superior oblique muscle, he is facing difficulty in the downward and lateral movement of the eyeball, as these functions are performed by the superior oblique muscle. Trochlear nerve nuclei are present in the midbrain at the level of the inferior colliculus.</p>\n<p><strong>Highyeild:</strong></p><p>The trochlear nerve is the 4th cranial nerve. It is purely motor and supplies only one muscle—the superior oblique muscle of the eyeball. Origin, course, and distribution of the trochlear nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect The Abducens nerve supplies the lateral rectus muscle of the eyeball. The lateral rectus muscle is responsible for abduction of the eyeball only, it does not cause depression of the eyeball. But superior oblique muscle causes depression as well as the abduction of the eyeball. So in this patient, the superior oblique is damaged, as the symptoms indicate. Abducens nerve nuclei are present in lower pons at the pontomedullary junction. Option: C. Incorrect As the facial nerve does not supply the muscles of the eyeball and it is not even related to eyeball movement. Facial nerve nuclei are present in lower pons at the pontomedullary junction. Option: D. Incorrect As the trochlear nerve is damaged in this case, there is paralysis of the superior oblique muscle. So the patient has problems with the abduction and depression movement of the eyeball. But trochlear nerve nuclei are present in the midbrain at the level of the inferior colliculus, not at the superior colliculus level.</p>\n<p><strong>Extraedge:</strong></p><p>Lesions of trochlear nerve: The injury of a trochlear nerve will cause paralysis of the superior oblique muscle of the eyeball. This will clinically present as Extorsion of the eyeball and weakness of downward gaze. As a result, the patient faces difficulty while going downstairs or reading the newspaper, and Diplopia (double vision), occurs when the patient looks laterally and glances looking downward. There is compensatory head-tilting to the opposite side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 40-year-old male patient arrived in your clinic, with a complaint of diplopia and ptosis. On examination, you find that he is having dilated pupils, loss of accommodation and loss of pupillary light reflex. No signs of blindness are found. Which nerve is involved in this case and what is the reason for the loss of pupillary and accommodation reflex in this case?", "options": [{"label": "A", "text": "Oculomotor nerve; loss of pupillary reflex due to damaged parasympathetic fibres of Edinger Westphal nucleus.", "correct": true}, {"label": "B", "text": "Optic nerve; lesion of the optic tract", "correct": false}, {"label": "C", "text": "Facial nerve; damage to Edinger Westphal nucleus", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Oculomotor nerve; loss of pupillary reflex due to damaged parasympathetic fibres of Edinger Westphal nucleus.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Oculomotor nerve; loss of pupillary reflex due to damaged parasympathetic fibres of Edinger Westphal nucleus. The Oculomotor nerve is damaged in this case, as paralysis of the oculomotor nerve leads to conditions like ptosis due to paralysis of the voluntary part of the levator palpebrae superioris muscle. Pupillary light reflex is absent in the affected eye and dilation of the pupil is found because of paralysis of parasympathetic fibres from the Edinger Westphal nucleus which travels along the oculomotor nerve, these supply sphincter pupillae muscle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Is incorrect Optic nerve damage leads to complete blindness, it is not found in this case. and lesion of the optic tract leads to homonymous hemianopia on the opposite side. Option: C. Incorrect Facial nerves do not supply any structure within the eyeball So it is not related to ptosis and diplopia found in this case. It supplies the facial muscles that maintain facial expression. Edinger Westphal nucleus is closely related to the oculomotor nerve nucleus in the midbrain. It supplies parasympathetic fibres to sphincter pupillae and ciliaris muscle. Option D. None of the above The Oculomotor nerve is damaged in this case, as paralysis of the oculomotor nerve leads to conditions like ptosis due to paralysis of the voluntary part of the levator palpebrae superioris muscle. Pupillary light reflex is absent in the affected eye and dilation of the pupil is found because of paralysis of parasympathetic fibres from the Edinger Westphal nucleus which travels along the oculomotor nerve, these supply sphincter pupillae muscle.</p>\n<p><strong>Extraedge:</strong></p><p>The damage of the oculomotor nerve clinically presents as: Ptosis (drooping of the upper eyelid), due to paralysis of the levator palpebrae superioris. Lateral strabismus (lateral squint), due to paralysis of the medial rectus and consequent unopposed action of the lateral rectus muscle. Dilated and fixed pupil, due to paralysis of the sphincter pupillae and consequent unopposed action of the dilator pupillae. Loss of accommodation, due to paralysis of the medial rectus, sphincter pupillae, and ciliaris muscles. Double vision or diplopia occurs on looking medially, inferiorly, and superiorly, due to paralysis of the medial rectus, inferior rectus, and inferior oblique muscles. Proptosis (prominence of the eyeball) due to relaxation of the muscles of the eyeball.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient arrived in the outpatient department, he has a complaint of defective speech due to sluggish movement of the tongue. On examination, it was found that the tongue is deviated to the right side. The doctor diagnosed him with 12th nerve paralysis. What are the functional nuclei columns which are damaged in this case?", "options": [{"label": "A", "text": "Special visceral efferent", "correct": false}, {"label": "B", "text": "Special somatic afferent", "correct": false}, {"label": "C", "text": "General somatic efferent and general somatic afferent", "correct": true}, {"label": "D", "text": "All of the above", "correct": false}], "correct_answer": "C. General somatic efferent and general somatic afferent", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>General somatic efferent and general somatic afferent Hypoglossal nerve supplies the muscle of the tongue, whose unilateral paralysis results in deviation of the tongue to the same side. It has a general somatic efferent column whose function is related to the movements of the tongue and a general somatic afferent column as it carries proprioceptive fibres from the</p>\n<p><strong>Highyeild:</strong></p><p>The hypoglossal nerve gives the following branches: Branches of the hypoglossal proper: They supply all the muscles of the tongue except palatoglossus which is supplied by the cranial root of the accessory via the pharyngeal plexus. Branches of the hypoglossal nerve containing C1 fibres: These are as follows: Meningeal branch: It arises from the nerve as it comes out through the hypoglossal canal taking a recurrent course, enters the cranial cavity through the hypoglossal canal, and supplies the dura mater of the posterior cranial fossa. Descendens hypoglossi or upper root of ansa cervicalis: It arises as the nerve crosses in front of the internal carotid artery. It runs downward to join the inferior root of ansa cervicalis at the level of cricoid cartilage. Nerve to thyrohyoid: It crosses the greater cornu of the hyoid bone to reach the muscle. Nerve to geniohyoid: It arises from above the hyoid bone.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect As the special visceral efferent column is related to the 5;7;9 and 10 the cranial nerve and its function is to supply muscles of branchial arches Option B. Incorrect A special somatic afferent column is related to the function of vision; olfaction and hearing. The optic, olfactory and vestibulocochlear nerve is the nerve having this column Option D. Incorrect The optic nerve has visual functions. An olfactory nerve has olfaction functions. So they are not having any function related to tongue muscles. Extraedge Lesions of hypoglossal nerve: If the hypoglossal nerve is cut on one side, there will be a lower motor neuron type of paralysis of the muscles of the tongue on that side. On asking the patient to protrude his tongue, the tip of the tongue deviates to the paralyzed side due to the unopposed action of the muscles of the healthy side.</p>\n<p><strong>Extraedge:</strong></p><p>Lesions of hypoglossal nerve: If the hypoglossal nerve is cut on one side, there will be a lower motor neuron type of paralysis of the muscles of the tongue on that side. On asking the patient to protrude his tongue, the tip of the tongue deviates to the paralyzed side due to the unopposed action of the muscles of the healthy side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A male patient of age 32 years old, on examination is found to have impairment of appreciation of pain and temperature of the face only. The doctor diagnosed this case as trigeminal nerve damage. Which nucleus of the trigeminal nerve is possibly damaged in this case?", "options": [{"label": "A", "text": "Spinal nucleus of the trigeminal nerve", "correct": true}, {"label": "B", "text": "Principal sensory nucleus of the trigeminal nerve", "correct": false}, {"label": "C", "text": "Mesencephalic nucleus of the trigeminal nerve", "correct": false}, {"label": "D", "text": "Motor nucleus of the trigeminal nerve", "correct": false}], "correct_answer": "A. Spinal nucleus of the trigeminal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spinal nucleus of the trigeminal nerve The trigeminal nerve sub-serves sensation from the face and neighbouring areas. It also innervates the muscles of mastication The spinal nucleus of the trigeminal nerve is damaged in this case. Fibres conveying pain and temperature sensations from most face area relay here. So, if it is damaged, pain and temperature sensations of the face will be lost.</p>\n<p><strong>Highyeild:</strong></p><p>Functional Components and Nuclei Special visceral efferent fibres . They arise from motor the nucleus of the trigeminal nerve in the pons and supply the muscles derived from the 1st pharyngeal arch, the muscles of mastication, mylohyoid, anterior belly of digastric, tensor palati, and tensor tympani. General somatic afferent fibres: (a) They carry exteroceptive sensations(i.e., pain, touch, and temperature) from the skin of the head and face, mucous membrane of the mouth, nasal cavity, meninges, etc. and terminate in the main sensory nucleus and spinal nucleus of the trigeminal nerve. (b) They also carry proprioceptive sensations from the muscles of mastication, temporomandibular joint, and teeth and terminate in the mesencephalic nucleus of the trigeminal nerve and the reticular formation of the brainstem. The exteroceptive neurons are pseudounipolar and their cell bodies are located in the trigeminal ganglion. The proprioceptive neurons are unipolar and their cell bodies are located in the mesencephalic nucleus of the trigeminal nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect The Principal sensory nucleus of the trigeminal nerve is having the fibres of touch and pressure from the face area. If they are damaged, touch and pressure sensations of the face are lost. Option: C. Incorrect Mesencephalic nuclei of trigeminal nerves receive proprioceptive impulses from muscles of mastication. Option: D. Incorrect The motor nucleus of the trigeminal nerve supplies the muscles of the first branchial arch. If they are injured that leads to paralysis of muscles of mastication.</p>\n<p><strong>Extraedge:</strong></p><p>The mesencephalic nucleus is the only site in the CNS which contains unipolar neurons/first-order sensory neurons.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A male patient of 40 years old is having a complaint of anosmia for the previous few weeks. He is also having complaints of headaches and seizures. The doctor advised him to have a CT scan of his brain. The CT scan shows an extra-axial mass, with a well-defined border and dural attachment. The doctor diagnosed it as meningioma in anterior cranial fossa. What is the cause of anosmia here?", "options": [{"label": "A", "text": "Compression of the facial nerve", "correct": false}, {"label": "B", "text": "Compression of the olfactory bulb and olfactory tract", "correct": true}, {"label": "C", "text": "Compression on vagus nerve", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "B. Compression of the olfactory bulb and olfactory tract", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Compression of the olfactory bulb and olfactory tract Meningioma of the anterior cranial fossa may compress the olfactory bulb and olfactory tract resulting in anosmia means loss of smell sensations. As the olfactory bulbs are located in the frontal part of the anterior cranial fossa, they are commonly damaged in meningioma of the anterior cranial fossa.</p>\n<p><strong>Highyeild:</strong></p><p>Functional Components Special somatic afferent fibres : They carry special sensations of smell from the olfactory region of the nasal cavity and terminate in the olfactory bulb.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect Facial nerve nuclei are present in the lower pons region at the pontomedullary junction; it is not involved in the lesion of the anterior cranial fossa. And the facial nerve is not related to the function of smell sensations. Option: C. Incorrect The vagus nerve is present in the medulla region not in the anterior cranial fossa. So it cannot be damaged in lesions of the anterior cranial fossa and is even not related to the sense of smell. Option D. None of the above. Meningioma of the anterior cranial fossa may compress the olfactory bulb and olfactory tract resulting in anosmia means loss of smell sensations.</p>\n<p><strong>Extraedge:</strong></p><p>Anosmia: The loss of sense of smell is called anosmia. Anosmia can occur for a number of reasons such as atrophic rhinitis (a degenerative disorder of nasal mucosa), fracture of the anterior cranial fossa (ethmoidal fracture), etc. The ethmoidal fracture is often associated with blood-stained cerebrospinal fluid (CSF rhinorrhea).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 60-year-old lady is diagnosed as having an advanced carcinoma of the nasopharynx with neoplastic infiltrations of the posterior cranial fossa. She has a chief complaint of loss of taste sensations over the posterior 1/3rd of the tongue. The uvula is found elevated in the midline and she can shrug her shoulders by using trapezius muscles normally. Which nerve is damaged in this case?", "options": [{"label": "A", "text": "Facial Nerve", "correct": false}, {"label": "B", "text": "Spinal accessory nerve", "correct": false}, {"label": "C", "text": "Vagus nerve", "correct": false}, {"label": "D", "text": "Glossopharyngeal nerve", "correct": true}], "correct_answer": "D. Glossopharyngeal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Glossopharyngeal nerve The glossopharyngeal nerve is present in the medulla region. It supplies the posterior 1/3rd of the tongue and sub-serves common sensations and taste sensations from there If it is damaged the posterior 1/3rd of taste sensations of the tongue is lost, as found in this case.</p>\n<p><strong>Highyeild:</strong></p><p>Functional Components and Nuclei Special visceral efferent fibres: They supply the stylopharyngeus muscle. They arise from the nucleus ambiguous. General visceral efferent fibres: They supply the secretomotor fibres to the parotid gland. They are preganglionic parasympathetic fibres and arise from the inferior salivatory nucleus. ; Special visceral afferent fibres: They carry taste sensations from the posterior one-third of the tongue including vallate papillae and terminate in the nucleus tractus solitarius. General visceral afferent fibres : They carry general sensations of pain, touch, and temperature from the mucous membrane of the pharynx, tonsil, soft palate, and the posterior one-third of the tongue and terminate in the dorsal nucleus of the vagus. General somatic afferent fibres : They carry proprioceptive sensations from the stylopharyngeus and skin of the auricle and terminate in the nucleus of the spinal tract of the 5th nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect The facial nerve arises from the lower pons area. It is carrying the taste sensations from the anterior 2/3rd of the tongue. So if it is damaged then taste is to be lost from the anterior 2/3rd area of the Option: B. Incorrect spinal accessory nerve supplies trapezius and sternocleidomastoid muscles If it is damaged then the patient is not able to shrug the shoulders properly, due to the paralysis of the trapezius muscle. Option: C. Incorrect The vagus nerve supplies the muscles of the palate, pharynx and larynx and it is responsible for maintaining the palatal arches. If it is damaged uvula deviated to the opposite side</p>\n<p><strong>Extraedge:</strong></p><p>Vernet syndrome refers to paralysis of the IX, X, and XI cranial nerves traversing the jugular foramen. A variety of lesions can involve the jugular foramen, such as tumours, vascular lesions, infections, and trauma.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 70-year-old male consults a physician, as he is becoming deaf. He is annoyed to find that his head size has increased, in a couple of months. He has also complained of headaches for the past few days. He has no other symptoms. The doctor asked him to protrude his tongue and he found the tongue protruded straight forwards. The doctor advised the patient for a CT scan after looking at the CT scan the doctor found increased cranial bone thickness and slight compression in the brain size. What is your diagnosis for this disease and its symptoms?", "options": [{"label": "A", "text": "Paget's disease; compression of vestibulocochlear nerve", "correct": true}, {"label": "B", "text": "Gorham stout disease; compression of vestibulocochlear nerve", "correct": false}, {"label": "C", "text": "Paget's disease; compression of hypoglossal nerve", "correct": false}, {"label": "D", "text": "All of the above", "correct": false}], "correct_answer": "A. Paget's disease; compression of vestibulocochlear nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Paget's disease; compression of vestibulocochlear nerve In Paget's disease of bones, there is an increased thickening of bone found due to new bone mass formation. As a result the thickness of the calvarium increases, which leads to compression of brain and cranial nerves which pass through small and narrower openings. Usually for vestibulocochlear nerve as it passes through the narrowing of the internal acoustic meatus. Compression of vestibulocochlear nerves leads to hearing loss, as found here.</p>\n<p><strong>Highyeild:</strong></p><p>Functional Component and Nuclei Special somatic afferent fibres : They carry sensory information necessary for the maintenance of equilibrium and hearing from the membranous labyrinth of the internal ear. The fibres carrying the sensory information for equilibrium terminate in the vestibular nuclei within the brainstem. The fibres carrying the sensory information for hearing terminate in the dorsal and ventral cochlear nuclei, located respectively on the dorsal and ventral aspects of the inferior cerebellar peduncle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect Vestibulocochlear nerve is responsible for hearing function but Gorham stout disease is a vanishing bone disease with progressive bone loss found due to osteolysis this is not found in this case, even though there is a thickening of bones found here Option: C. Incorrect Hypoglossal nerves arise from the medulla, and it supplies mainly to the tongue muscle. If it is compressed, the tongue will deviate to the paralyzed side. But no such deviation was found in this patient. Option: D. Is incorrect As option b and option c are incorrect, all of the above cannot be the answer.</p>\n<p><strong>Extraedge:</strong></p><p>Lesions of vestibulocochlear nerve: The lesions of the vestibulocochlear nerve clinically present as (a) tinnitus (ringing or buzzing in the ears), (b) impairment or loss of hearing, and (c) loss of balance (vertigo) The vestibular nerve is commonly involved by the acoustic neuroma, which arises from the sheath cells of its constituent fibres in the region of the cerebellopontine angle. Acoustic neuroma is one of the common intracranial tumours, and if large, it may involve the adjacent trigeminal, facial, and glossopharyngeal nerves and may compress the cerebellum and medulla.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A female patient of 32 years old is diagnosed with syringomyelia. On a physical examination, she is found to have no impairment of appreciation of pain and temperature of the face, but she is having an impairment of appreciation of light touch, pain and temperature sensations from the lower body parts is preserved. What are the most problematic nuclei/sites of damage?", "options": [{"label": "A", "text": "Lesion in the anterolateral column of the spinal cord", "correct": false}, {"label": "B", "text": "Lesion in the motor nuclei of the facial nerve", "correct": false}, {"label": "C", "text": "Lesion in the spinal nuclei of the trigeminal nerve", "correct": false}, {"label": "D", "text": "Lesion in principal sensory nuclei of the trigeminal nerve", "correct": true}], "correct_answer": "D. Lesion in principal sensory nuclei of the trigeminal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lesion in principal sensory nuclei of the trigeminal nerve The trigeminal nerve is the largest cranial nerve. It has three branches, two of which are purely sensory and the third one is mixed. The principal sensory nucleus of the trigeminal nerve is basically carrying the fibres of touch and pressure sensations from the face area. If they are damaged, the patient's touch and pressure sensations in the face area will be lost.</p>\n<p><strong>Highyeild:</strong></p><p>In the middle cranial fossa, the sensory root expands into the trigeminal ganglion , which contains cell bodies for the sensory neurons in the trigeminal nerve and is comparable to a spinal ganglion. The ganglion is in a depression (the trigeminal depression) on the anterior surface of the petrous part of the temporal bone, in a dural cave (the trigeminal cave ). The motor root is below and completely separate from the sensory root at this point. The cranial nerve nuclei</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect We know that the anterolateral column of the spinal cord carries pain, light touch and temperature sensations of lower body parts. So, if they are damaged, the pain, temperature and touch sensations are lost in the lower body, which is preserved in this case. Option: B. Incorrect As the motor nuclei of the facial nerve supply the muscles of facial expression and carry out their movements. If it is damaged, the facial expression of the patient will be lost. Option: C. Incorrect Because the spinal nuclei of trigeminal nerves have fibres conveying pain and temperature sensations in the face. So if it is damaged pain and temperature sensation of the face are lost</p>\n<p><strong>Extraedge:</strong></p><p>The trigeminal nerve [V] is the major general sensory nerve of the head and also innervates muscles that move the lower jaw. It carries general somatic afferent (GSA) and branchial efferent (BE) fibres : The GSA fibres provide sensory input from the face, anterior one-half of the scalp, mucous membranes of the oral and nasal cavities and the paranasal sinuses, the nasopharynx, part of the ear and external acoustic meatus, part of the tympanic membrane, the orbital contents and conjunctiva, and the dura mater in the anterior and middle cranial fossae. The BE fibres innervate the muscles of mastication; the tensor tympani, tensor veli palatini, and mylohyoid muscles; and the anterior belly of the digastric muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient is admitted to the emergency department having symptoms like headache, nausea and vomiting. The doctor advised the patient to get an MRI done. The MRI scan shows neoplastic growth in the medulla region. She is diagnosed with advanced-stage carcinoma of the medulla oblongata. All of the given signs and symptoms are found in the patient except:", "options": [{"label": "A", "text": "Loss of taste sensation from posterior 2/3rd of tongue", "correct": false}, {"label": "B", "text": "Blindness", "correct": true}, {"label": "C", "text": "Complete paralysis of the tongue", "correct": false}, {"label": "D", "text": "Weakness in shrugging the shoulders", "correct": false}], "correct_answer": "B. Blindness", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Blindness Blindness is not found in case of carcinoma of the medulla as blindness of the eye is found in cases of damage to the optic nerve is found in the anterior cranial region, not in the medulla so the medullary carcinoma has no effect on the optic nerve.</p>\n<p><strong>Highyeild:</strong></p><p>The optic nerve [II] carries SA (sensory afferent) fibres for vision . These fibres return information to the brain from photoreceptors in the retina. Neuronal processes leave the retinal receptors, join into small bundles, and are carried by the optic nerves to other components of the visual system in the brain. The optic nerves enter the cranial cavity through the optic canals.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect Because the glossopharyngeal nerve is attached to the upper part of the posterolateral sulcus of the medulla, it is damaged in the cases of medullary carcinoma. Damage to this nerve leads to loss of taste sensation from the posterior 1/3rd of the tongue. Option: C. Incorrect Complete paralysis of the tongue is seen in cases of bilateral paralysis of the 12th nerve. The hypoglossal nerve is attached to the anterolateral sulcus of the medulla, so it is affected in cases of medullary carcinoma it supplies to the muscles of the tongue. Option: D. Incorrect Weakness in shrugging of the shoulders is commonly seen in cases of damage to the cranial part of the accessory nerve cranial root emerging from the posterolateral sulcus of the medulla; it is also commonly damaged in cases of carcinoma of the</p>\n<p><strong>Extraedge:</strong></p><p>The optic nerve has been classified as the second of twelve paired cranial nerves, but it is technically a myelinated tract of the central nervous system , rather than a classical nerve of the peripheral nervous system because it is derived from an out-pouching of the diencephalon (optic stalks) during embryonic development.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A doctor on examination of a male patient of 40 years old found drooping of the shoulder and an inability to turn his chin to the opposite side. According to you, what is the structure damaged in this case?", "options": [{"label": "A", "text": "Lesion to the spinal root of the accessory nerve", "correct": true}, {"label": "B", "text": "Lesion to the glossopharyngeal nerve", "correct": false}, {"label": "C", "text": "Lesion to the upper lateral cutaneous nerve of the arm", "correct": false}, {"label": "D", "text": "Lesion to supraclavicular nerve", "correct": false}], "correct_answer": "A. Lesion to the spinal root of the accessory nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lesion to the spinal root of the accessory nerve The spinal part of the accessory nerve arises from the spinal nucleus of the accessory nerve which is situated in the C1-C5 segment of the spinal cord. It supplies to the sternocleidomastoid and trapezius muscles, both of which are important for movements like shrugging of the shoulder and moving the chin to the opposite side. So lesion to the spinal root of the accessory nerve causes drooping of the shoulder and the inability to turn the chin to the opposite side.</p>\n<p><strong>Highyeild:</strong></p><p>The accessory nerve [XI] is a cranial nerve that carries GSE fibres to innervate the sternocleidomastoid and trapezius muscles. It is a unique cranial nerve because its roots arise from motor neurons in the upper five segments of the cervical spinal cord. These fibres leave the lateral surface of the spinal cord and, joining together as they ascend, enter the cranial cavity through the foramen magnum. The accessory nerve [XI] continues through the posterior cranial fossa and exits through the jugular foramen. It then descends in the neck to innervate the sternocleidomastoid and trapezius muscles from their deep surfaces.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect The glossopharyngeal nerve is carrying the taste sensation from the posterior 1/3rd of the tongue and if it is damaged the patient will have a loss of taste sensations from the posterior 1/3rd tongue Option: C. Incorrect The upper lateral cutaneous nerve of the arm is responsible for carrying sensory sensations from the upper lateral arm region. If it is damaged it leads to loss of sensory sensation over the upper lateral side of the arm Option: D. Incorrect The supraclavicular nerve is providing the sensory sensations from the clavicle and anteromedial shoulder If it is damaged, there is a loss of sensation from these areas.</p>\n<p><strong>Extraedge:</strong></p><p>The accessory nerve is derived from the basal plate of the embryonic spinal segments C1–C6.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The boy fell from a running bus, which partially ran over him and caused injury to the base of his skull. The origin of the internal jugular vein at the jugular foramen was compromised. Which of the following cranial nerves courses through the jugular foramen?", "options": [{"label": "A", "text": "Abducens (sixth cranial) nerve", "correct": false}, {"label": "B", "text": "Facial (seventh cranial) nerve", "correct": false}, {"label": "C", "text": "Hypoglossal (twelfth cranial) nerve", "correct": false}, {"label": "D", "text": "Spinal accessory nerve (eleventh cranial) nerve", "correct": true}], "correct_answer": "D. Spinal accessory nerve (eleventh cranial) nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spinal accessory nerve (eleventh cranial) nerve The spinal accessory (eleventh cranial) nerve takes its origins in the neck, but then runs cranially into the skull through the foramen magnum to join with its cranial component. They exist as one through the jugular foramen , along with the glossopharyngeal (ninth cranial) and vagus (tenth cranial) nerves.</p>\n<p><strong>Highyeild:</strong></p><p>The cranial root of the accessory nerve via the vagus nerve and pharyngeal plexus of nerves supplies: All the muscles of the palate except the tensor palati and tensor tympani are supplied by the mandibular nerve (nerve to medial pterygoid). All The muscles of the pharynx except the Stylopharyngeus which is supplied by the glossopharyngeal nerve. All the intrinsic muscles of the larynx. The spinal root of the accessory nerve supplies the following two muscles: The sternocleidomastoid muscle along with C2 and C3 spinal nerves. Trapezius muscle along with C3 and C4 spinal nerves.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. The abducens (sixth cranial) nerve runs through the superior orbital fissure to reach the orbit. Option: B. The facial (seventh cranial; ) and vestibulocochlear nerves run together through the internal acoustic meatus into the temporal bone. The facial nerve exits the skull through the stylomastoid foramen. Option: C. The hypoglossal (twelfth cranial; ) nerve exits the skull through the hypoglossal canal.</p>\n<p><strong>Extraedge:</strong></p><p>Functional Components and Nuclei Special visceral efferent fibres : provide motor supply to the muscles of the soft palate, pharynx, and larynx. They arise from the nucleus ambiguous and form the cranial root. General somatic efferent fibres: provide motor supply to the sternocleidomastoid and trapezius muscles. They arise from the spinal nucleus of the accessory nerve, in the ventral horns of the upper five spinal segments and form the spinal root.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Palsy of which nerve in the following Image causes the inability to produce horizontal, conjugate eye movements in one or both directions?", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": true}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "B. B", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681287396-QTDA021015IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>B Lateral gaze palsy is an inability to produce horizontal, conjugate eye movements in one or both directions. Lesions of the cranial nerve VI (abducens) nucleus in the pons cause ipsilateral, lateral gaze palsy. The given image is of Cavernous Sinus where A= Oculomotor Nerve (III) B= Abducens Nerve (VI) C= Ophthalmic Nerve (V) D= Maxillary Nerve</p>\n<p><strong>Highyeild:</strong></p><p>From above downward these are as follows: Oculomotor nerve. Trochlear nerve. Ophthalmic nerve. Maxillary nerve. Structures Passing Through Cavernous Sinus The internal carotid artery is surrounded by the sympathetic plexus of nerves. Abducens nerve (it enters the sinus by passing below the petrosphenoid ligament and accompanies the artery on its inferolateral aspect).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. A A is Oculomotor Nerve (III) Oculomotor nerve palsy will result in a characteristic down-and-out position in the affected eye. The eye will be displaced outward \"exotropia\" and displaced downward \"hypotropia\"; outward because the lateral rectus (innervated by the sixth cranial nerve) maintains muscle tone in comparison to the paralyzed medial rectus. Option C. C C is Ophthalmic Nerve (V) In injury of the ophthalmic nerve, there is loss of corneal blink reflex. Option D. D The maxillary nerve is the second branch of the trigeminal nerve, which originates embryologically from the first pharyngeal arch. Its primary function is sensory supply to the mid-third of the face. In cases of injury to the maxillary nerve, there is a loss of the sneeze reflex. This branch is the afferent path for the sneeze reflex.</p>\n<p><strong>Extraedge:</strong></p><p>Dangerous area of the face : The facial vein and its communications are devoid of valves in their lumens. Since the facial vein rests directly on the muscles of facial expression, the movements of these muscles may facilitate the spread of septic emboli from the infected area of the lower part of the nose, upper lip, and adjoining part of the cheek in a retrograde direction through the deep facial vein, pterygoid venous plexus, and emissary's vein into the cavernous sinus leading to meningitis and cavernous sinus thrombosis. For this reason, this portion of the face is called the dangerous area of the face.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Intraocular muscle supplied by Edinger Westphal nucleus is:", "options": [{"label": "A", "text": "Superior Oblique", "correct": false}, {"label": "B", "text": "Ciliary muscle", "correct": true}, {"label": "C", "text": "Lateral rectus", "correct": false}, {"label": "D", "text": "Medial rectus", "correct": false}], "correct_answer": "B. Ciliary muscle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ciliary muscle Edinger Westphal nucleus sends the Preganglionic parasympathetic fibres through the oculomotor nerve to the ciliary ganglion, which further supplies two smooth muscles of the eyeball: ciliary and sphincter papilla</p>\n<p><strong>Highyeild:</strong></p><p>The parasympathetic root arises from the nerve to the inferior oblique. It contains preganglionic fibres that begin in the Edinger-Westphal nucleus. The fibres relay in the ciliary ganglion. Postganglionic fibres arising in the ganglion pass through the short ciliary nerves and supply the sphincter pupillae and the ciliaris muscle. Edinger Westphal nucleus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Superior Oblique The superior oblique is innervated by the trochlear nerve. Option C. Lateral rectus The lateral rectus is innervated by the abducens nerve. Option D. Medial rectus The medial rectus is innervated by the oculomotor nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The sympathetic root is a branch from the internal carotid plexus. It contains postganglionic fibres arising in the superior cervical ganglion (preganglionic fibres reach the ganglion from the lateral horn of the T1 spinal segment) which pass along internal carotid, ophthalmic and long ciliary arteries. They pass out of the ciliary ganglion without relaying in the short ciliary nerves to supply the blood vessels of the eyeball. They also supply the dilator pupillae.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following sensation is not perceived by the spinal nucleus of the trigeminal nerve?", "options": [{"label": "A", "text": "Pain", "correct": false}, {"label": "B", "text": "Touch", "correct": false}, {"label": "C", "text": "Temperature", "correct": false}, {"label": "D", "text": "Proprioception", "correct": true}], "correct_answer": "D. Proprioception", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Proprioception Proprioception is the function of the Mesencephalic nucleus of the Trigeminal nerve.</p>\n<p><strong>Highyeild:</strong></p><p>General Somatic Afferent Nuclei: These are all related to the trigeminal nerve. The main or superior sensory nucleus of the trigeminal nerve lies in the upper part of the pons The spinal nucleus of the trigeminal nerve descends from the main nucleus into the medulla. The mesencephalic nucleus of the trigeminal nerve extends upwards from the main sensory nucleus into the midbrain</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Pain, option B. Touch and option C. Temperature, All these sensations are perceived by the spinal nucleus of the trigeminal nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The spinal trigeminal nucleus is a nucleus in the medulla that receives information about deep/crude touch, pain, and temperature from the ipsilateral face. In addition to the trigeminal nerve (CN V), the facial (CN VII), glossopharyngeal (CN IX), and vagus nerves (CN X) also convey pain information from their areas to the spinal trigeminal nucleus. [1] Thus the spinal trigeminal nucleus receives input from cranial nerves V, VII, IX, and X.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All the following statements about the vagus nerve are true except:", "options": [{"label": "A", "text": "Supplies heart and lung", "correct": false}, {"label": "B", "text": "Carries postganglionic parasympathetic fibres", "correct": true}, {"label": "C", "text": "Innervates up to right two-thirds of the transverse colon", "correct": false}, {"label": "D", "text": "Stimulates peristalsis and relaxes sphincters", "correct": false}], "correct_answer": "B. Carries postganglionic parasympathetic fibres", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Carries postganglionic parasympathetic fibres Vagus nerve carries preganglionic fibres not postganglionic.</p>\n<p><strong>Highyeild:</strong></p><p>The Vagus leaves the cranial cavity through the jugular foramen lying posterior to the IX nerve. Soon it is joined by the cranial root of the XI nerve. In the neck, the nerve lies in the carotid sheath, medial to internal jugular vein and posterior to internal carotid and common carotid arteries. Then it passes through the thorax and abdomen. Branches of Vagus nerve in Neck Meningeal Auricular Pharyngeal for most muscles of the soft palate 4 out of 5 and pharynx 5 out 6, carotid for carotid body and carotid sinus, The superior laryngeal gives internal laryngeal for the mucous membrane of the larynx and external laryngeal for cricothyroid muscle. The right recurrent laryngeal is given off in the neck while the left one is given off in the thorax. The nerves supply all intrinsic muscles of the larynx, and sensory branches to the mucous membrane of the larynx below the vocal cords. Cardiac branches for deep cardiac plexus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Supplies heart and lung Both the right and left vagus nerves descend from the brain in the carotid sheath, lateral to the carotid artery. The nerve runs from the lower brain stem through the base of the skull to travel in the neck with the carotid artery and jugular vein. It then penetrates the chest to travel to the heart and lungs. Option C. Innervates up to the right two-thirds of the transverse colon The vagus innervates the right two-thirds of the transverse colon. Option D. Stimulates peristalsis and relaxes sphincters The vagus nerve Stimulates peristalsis and relaxes sphincters.</p>\n<p><strong>Extraedge:</strong></p><p>Alderman’s nerve phenomenon: The tickling of the cutaneous distribution of the vagus nerve stimulates a jaded appetite. The Alderman in ancient Roman days used to stimulate their appetite by dropping cold water behind the ear supplied by the auricular branch of the vagus nerve. For this reason, the auricular branch of the vagus nerve is also called Alderman’s nerve. Apparently, this occurs by a reflex increase in gastric motility supplied by the vagus nerve (to the stomach). Lesions of the vagus nerve: The bilateral lesions of the vagus nerve cause: Nasal regurgitation of the swallowed liquids, The nasal twang of voice hoarseness of voice, flattering of palatal arches, cadaveric position of vocal cards, dysphagia, and loss of cough reflex.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Special visceral Efferent fibres supply:", "options": [{"label": "A", "text": "Striated muscles of the limb", "correct": false}, {"label": "B", "text": "Muscles of mastication", "correct": true}, {"label": "C", "text": "Extrinsic muscles of the limb", "correct": false}, {"label": "D", "text": "Musculature of the iris", "correct": false}], "correct_answer": "B. Muscles of mastication", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Muscles of mastication SVE includes the nucleus of the nerve supplying pharyngeal arches- V3, VII, IX, X, XI, V3 nerve supplies muscles of mastication.</p>\n<p><strong>Highyeild:</strong></p><p>Special Visceral Efferent/Branchial Efferent Nuclei These nuclei supply striated muscle derived from the branchial arches. The motor nucleus of the trigeminal nerve lies in the upper part of the pons. It supplies the muscles of mastication through the mandibular nerve. The nucleus of the facial nerve lies in the lower part of the pons. It supplies the various muscles innervated by the facial nerve. The nucleus ambiguity lies in the medulla. It forms an elongated column lying in both the open and closed parts of the medulla. It supplies The stylopharyngeus muscle through the glossopharyngeal nerve; and The muscles of the soft palate, the pharynx and the larynx through the vagus nerve and the cranial part of the accessory nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Striated muscles of the limb Skeletal muscle is supplied by somatic nerves. Option C. Extrinsic muscles of the limb The somatic nervous system is a component of the peripheral nervous system associated with the voluntary control of body movements via the use of skeletal muscles . Option D. Musculature of the iris The iris sphincter muscle receives its parasympathetic innervation via the short ciliary nerves which leads to pupillary constriction (miosis) and accommodation. The parasympathetic fibres that serve the sphincter muscle originate from the Edinger-Westphal nucleus of cranial nerve III.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The nucleus in the brain common to IX, X, XI cranial nerves:", "options": [{"label": "A", "text": "Nucleus Solitarius", "correct": false}, {"label": "B", "text": "Nucleus ambiguous", "correct": true}, {"label": "C", "text": "Dentate nucleus", "correct": false}, {"label": "D", "text": "Red nucleus", "correct": false}], "correct_answer": "B. Nucleus ambiguous", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Nucleus ambiguous The nucleus ambiguous provides innervation to the muscles of the soft palate, larynx, and pharynx by contributing motor fibres to three cranial nerves: glossopharyngeal (CN IX), vagus (CN X), and spinal accessory (CN XI) nerves.</p>\n<p><strong>Highyeild:</strong></p><p>This nucleus gives rise to the branchial efferent motor fibres of the vagus nerve (CN X) terminating in the laryngeal, pharyngeal muscles, and musculus uvulae as well as to the efferent motor fibres of the glossopharyngeal nerve (CN IX) terminating in the stylopharyngeus muscle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Nucleus Solitarius The nucleus of tractus solitarius , also known as the nucleus of the solitary tract or simply the solitary nucleus , is a purely sensory nucleus located in the dorsolateral medulla oblongata and lower pons. It receives many sensory inputs including taste information and sensory information from the middle ear, contributing to the facial, glossopharyngeal and vagus nerves Option C. Dentate nucleus The dentate nucleus is the largest deep cerebellar cluster of neurons; it has a dentated-serrated edge. Efferent fibres of the dentate nucleus are involved in the modulation of motor neurons and neurons involved in conscious thought and visuospatial function. Option D . Red nucleus The red nucleus or nucleus ruber is a structure in the rostral midbrain involved in motor coordination. The red nucleus is pale pink, which is believed to be due to the presence of iron in at least two different forms: haemoglobin and ferritin.</p>\n<p><strong>Extraedge:</strong></p><p>The nucleus is ambiguous controls the motor innervation of ipsilateral muscles of the soft palate, pharynx, larynx and upper esophagus. Lesions of nucleus ambiguus result in nasal speech, dysphagia, dysphonia, and deviation of the uvula toward the contralateral side. Preganglionic parasympathetic to the heart also flow through the external formation of the nucleus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "NOT a somatic efferent nerve:", "options": [{"label": "A", "text": "III", "correct": false}, {"label": "B", "text": "IV", "correct": false}, {"label": "C", "text": "V", "correct": true}, {"label": "D", "text": "XII", "correct": false}], "correct_answer": "C. V", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>V Cranial nerves III, IV, and VI (oculomotor, trochlear, and abducens nerves, respectively) are general somatic efferent (GSE) nerves responsible for innervating the extraocular muscles within the orbit, and cranial nerve XII innervates the muscle of the</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. III, option B. IV and Option D. XII All cranial nerves are somatic efferent nerves. Cranial nerves III, IV, and VI (oculomotor, trochlear, and abducens nerves, respectively) are general somatic efferent (GSE) nerves responsible for innervating the extraocular muscles within the orbit, and cranial nerve XII innervates the muscle of thetongue.</p>\n<p><strong>Extraedge:</strong></p><p>Functional Columns</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 31 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which among the following muscles are supplied by the facial nerve? Levator Anguli Oris Levator palpebrae superioris Levator labii superioris Zygomaticus major Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,2,4", "correct": false}, {"label": "B", "text": "1,3,4", "correct": true}, {"label": "C", "text": "1,4", "correct": false}, {"label": "D", "text": "3,4", "correct": false}], "correct_answer": "B. 1,3,4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,3,4 Levator palpebrae superioris is supplied by upper ramus of oculomotor nerve. That is why ptosis is a feature of 3rd nerve palsy Facial nerve supplies facial muscles. Levator palpebrae superioris is present in the roof of the orbit supplied by oculomotor</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The following statements concerning the chorda tympani nerve are true, EXCEPT:", "options": [{"label": "A", "text": "Carries the secretomotor fibres to the submandibular gland", "correct": false}, {"label": "B", "text": "Joins lingual nerve in infra-temporal fossa", "correct": false}, {"label": "C", "text": "Is a branch of the facial nerve", "correct": false}, {"label": "D", "text": "Contains postganglionic parasympathetic fibres", "correct": true}], "correct_answer": "D. Contains postganglionic parasympathetic fibres", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Contains postganglionic parasympathetic fibres Branch of the facial nerve Passes through the tympanic membrane at the junction of pars flaccid and Pars densa. Enters the infratemporal fossa through the medial end of the petrotympanic fissure It joins the posterior border of the lingual nerve at an acute angle. It conveys the pre-ganglionic secretomotor fibres to the submandibular and sublingual glands and taste fibres of the anterior two-thirds of the tongue.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Bill's bar divides?", "options": [{"label": "A", "text": "Facial nerve and cochlear nerve", "correct": false}, {"label": "B", "text": "Facial nerve and superior vestibular cochlear nerve", "correct": true}, {"label": "C", "text": "Facial and inferior vestibule cochlear nerve", "correct": false}, {"label": "D", "text": "Superior and inferior vestibule cochlear nerve", "correct": false}], "correct_answer": "B. Facial nerve and superior vestibular cochlear nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Facial nerve and superior vestibular cochlear nerve Bill’s bar divides the superior compartment of the internal acoustic meatus into an anterior and posterior compartment. Anterior to Bill’s bar, are the facial nerve (in the anterior superior quadrant) and nerves intermedius, and posterior to it is the superior division of the vestibular nerve (in the posterosuperior quadrant).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In which of the following condition there is ipsilateral 3rd nerve palsy with contralateral hemiplegia and facial palsy of the upper motor neuron?", "options": [{"label": "A", "text": "Weber Syndrome", "correct": true}, {"label": "B", "text": "Terson syndrome", "correct": false}, {"label": "C", "text": "Millard-Gubler syndrome", "correct": false}, {"label": "D", "text": "Foville's syndrome", "correct": false}], "correct_answer": "A. Weber Syndrome", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Weber Syndrome Weber syndrome: Characterized by ipsilateral CN 3 palsy, contralateral hemiplegia and facial palsy of upper motor neuron type.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B: Terson syndrome: Combination of bilateral intraocular haemorrhages and subarachnoid haemorrhage due to aneurysmal rupture. Option C: Millard-Gubler syndrome: Consist of ipsilateral CN 6 palsy, contralateral hemiplegia and ipsilateral facial palsy. Option D: Foville's syndrome CN of paralysis is replaced by a loss of conjugate movement on the same side.</p>\n<p><strong>Extraedge:</strong></p><p>Benedict's syndrome: Characterized by ipsilateral CN 3 by associated with tremors and jerky movements of the contralateral side due to involvement of the red nucleus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The facial recess or the posterior sinus is bounded by: Medially by the vertical part of the VII nerve Chorda tympani Above by the fossa incudis Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,2", "correct": false}, {"label": "B", "text": "2,3", "correct": false}, {"label": "C", "text": "1,3", "correct": false}, {"label": "D", "text": "1,2,3", "correct": true}], "correct_answer": "D. 1,2,3", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,2,3 Facial recess or Posterior sinus – It is a depression in the posterior wall of the middle ear. It is bounded by: Medially – Vertical part of VIII nerve Laterally – Chorda tympani Above – Fossa incudis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following cranial nerves contain neurons from the general somatic efferent column? III Nerve IV nerve VI nerve VII nerve Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,3,4", "correct": false}, {"label": "B", "text": "1,2", "correct": false}, {"label": "C", "text": "2,4", "correct": false}, {"label": "D", "text": "1,2,3", "correct": true}], "correct_answer": "D. 1,2,3", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,2,3 The VII nerve (facial) does not contain neurons from the somatic efferent column. The general somatic efferent (GSE) is the most ventral column in the basal plate. It is represented by the oculomotor (III), trochlear (IV), abducens (VI), and hypoglossal (XII) nuclei. The facial (VII) nerve contains neurons from: Special visceral efferent (SVE) column - supplies facial muscles derived from the second pharyngeal arch. The general visceral efferent (GVE) column - from the superior salivatory nucleus, is parasympathetic to the lacrimal gland, submandibular and sublingual salivary glands.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options: A, B, C The general somatic efferent (GSE) is the most ventral column in the basal plate. It is represented by the oculomotor (III), trochlear (IV), abducens (VI), and hypoglossal (XII) nuclei.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following are used for the identification of the facial nerve trunk? Retrograde dissection from the distal branch Tragal pointer Inferior belly of omohyoid muscle Posterior belly of digastric Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,2,3", "correct": false}, {"label": "B", "text": "2,3,4", "correct": false}, {"label": "C", "text": "1,2,4", "correct": true}, {"label": "D", "text": "1,2,3,4", "correct": false}], "correct_answer": "C. 1,2,4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,2,4 The inferior belly of the omohyoid muscle is not used as an anatomical landmark for the identification of the facial nerve trunk. There are two methods for localization of the facial nerve trunk: Anterograde method: The facial nerve trunk is identified based on the anatomical landmarks after it exits from the stylomastoid foramen. This includes: -Tragal pointer/Conley's pointer - It is the inferior portion of the cartilaginous canal. The facial nerve trunk lies 1 cm deep and inferior to its tip. Posterior belly of digastric - The facial nerve lies superior to The upper border of The muscle. Squamotympanic fissure - It is a fissure in The temporal bone, which runs from TMJ to The tympanic cavity. The facial nerve runs through this fissure. Styloid process - The facial nerve lies superficial to it. Mastoid process - Upon drilling It, The nerve is identified proximally. Retrograde method: the main branches of the facial nerve trunks are identified and are then traced proximally until the main trunk is identified. Some branches used for tracing the facial nerve trunk include the Buccal branch: which lies in relation to the parotid gland. Marginal mandibular branch - it lies in relation to the facial vessels.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Regarding the stapedial reflex, which of the following is true?", "options": [{"label": "A", "text": "It helps to enhance the sound conduction in the middle ear", "correct": false}, {"label": "B", "text": "It is a protective reflex against loud sounds", "correct": true}, {"label": "C", "text": "It helps in masking the sound waves", "correct": false}, {"label": "D", "text": "It is a unilateral reflex", "correct": false}], "correct_answer": "B. It is a protective reflex against loud sounds", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>It is a protective reflex against loud sounds The Stapedius muscle helps to dampen very loud sounds and thus prevents noise trauma to the inner ear. It is supplied by the VII nerve (facial nerve). Lesions of facial nerve led to loss of stapedial reflex and hyperacusis or phonophobia i.e., intolerance to loud sounds.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "32-Year lady comes with fever, parotid enlargement and red eye. On examination, she has unilateral LMN facial palsy. The most likely diagnosis is:", "options": [{"label": "A", "text": "Lofgren's Syndrome", "correct": false}, {"label": "B", "text": "Mumps", "correct": false}, {"label": "C", "text": "Ramsay Hunt syndrome", "correct": false}, {"label": "D", "text": "Heerfordt's syndrome", "correct": true}], "correct_answer": "D. Heerfordt's syndrome", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Heerfordt's syndrome Herefordt – Waldenstrom: syndrome acute sarcoidosis which manifests with fever, parotid enlargement, anterior uveitis and facial nerve palsy.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option. A: Lofgren's syndrome is also a form of acute sarcoidosis presenting with erythema nodosum, arthritis and bilateral adenopathy. Option. B: Mumps is not associated with red eye and facial palsy. Option. C: Ramsay Hunt syndrome is LMN facial palsy and otalgia due to Herpes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient presented with weakness in the right side of the face with the loss of pain and temperature sensation on the left side of the body. The lesion is most likely located at the?", "options": [{"label": "A", "text": "Medial Medulla", "correct": false}, {"label": "B", "text": "Lateral pons", "correct": true}, {"label": "C", "text": "Medial pons", "correct": false}, {"label": "D", "text": "Lateral medulla", "correct": false}], "correct_answer": "B. Lateral pons", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral pons The lesion in the pons leads to the 7th nerve palsy as the 7th nerve nucleus is present in Pons leading to I/L facial weakness along with impairment of the sensory part of the 5th nerve (Present laterally in Pons) leading to I/L- loss of sensations on the As the pain and temp. The sensation of the left side (C/L) is also affected s/o of the lesion to the spinothalamic tract which runs laterally. In the case of lateral medullary syndrome or Wallenberg syndrome, all the symptoms mentioned above will be present. Along with those, there will be impairment of Vlll, IX, X and XI CN.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 20 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Identify the nerve marked in the given specimen of the neck.", "options": [{"label": "A", "text": "Glossopharyngeal Nerve", "correct": false}, {"label": "B", "text": "Lingual nerve", "correct": false}, {"label": "C", "text": "Hypoglossal nerve", "correct": true}, {"label": "D", "text": "Superior laryngeal nerve", "correct": false}], "correct_answer": "C. Hypoglossal nerve", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681311532-QTDA023001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Hypoglossal nerve The marked nerve in the given specimen is seen passing forward and superficial to carotid vessels (in a carotid triangle) and then deep to the posterior belly of the digastric to enter the digastric triangle. Hypoglossal nerve passing superficial to carotid vessels Within the carotid triangle, XII can also be seen giving off the nerve to the thyrohyoid (in the anterior part of the triangle).</p>\n<p><strong>Highyeild:</strong></p><p>The hypoglossal nerve runs forwards over the external and internal carotid arteries. The hypo-glossal nerve gives off the upper root of the ansa cervicalis or descendens hypoglossi, and another branch to the thyrohyoid.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Glossopharyngeal Nerve Deep structures, passing between the external and internal carotid arteries, are: The styloglossus The stylopharyngeus The glossopharyngeal nerve The pharyngeal branch of the vagus nerve The styloid process A part of the parotid gland. Option B. Lingual nerve The lingual nerve continues to run anteriorly, but now it turns medially to reach the tongue, travelling between the hyoglossus and mylohyoid muscles. The nerve extends to the hyoglossus's lateral aspect and gets to its front border. Option D. Superior laryngeal nerve The superior laryngeal nerve (SLN) originates commonly from the vagus nerve at the level of the C2 vertebra and descends medially toward the thyrohyoid membrane (TM), the membrane between the thyroid cartilage and the hyoid bone.</p>\n<p><strong>Extraedge:</strong></p><p>Superficial to the carotid sheath lies the hypoglossal nerve and ansa cervicalis of the cervical plexus. The hypoglossal nerve crosses both the internal and external carotids, curving around the origin of the occipital artery. Within the sheath, between the artery and vein, and behind both, is the vagus nerve; behind the sheath, the sympathetic trunk. On the lateral side of the vessels, the accessory nerve runs for a short distance before it pierces the Sternocleidomastoid; and on the medial side of the external carotid, just below the hyoid bone, the internal branch of the superior laryngeal nerve may be seen.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The cranial part of accessory nerve supplies:", "options": [{"label": "A", "text": "Sternocleidomastoid", "correct": false}, {"label": "B", "text": "Levator scapulae", "correct": false}, {"label": "C", "text": "Superior constrictor", "correct": true}, {"label": "D", "text": "Trapezius", "correct": false}], "correct_answer": "C. Superior constrictor", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior constrictor Cranial accessory - forms pharyngeal plexus which supplies muscles of palate and pharynx.</p>\n<p><strong>Highyeild:</strong></p><p>The spinal component of the accessory nerve provides motor control of the sternocleidomastoid and trapezius muscles. The trapezius muscle controls the action of shrugging the shoulders, and the sternocleidomastoid the action of turning the head . Contraction of the upper part of the trapezius muscle elevates the scapula. The cranial component of the accessory nerve, on the other hand, provides motor control to the muscles of the soft palate, larynx and pharynx.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Sternocleidomastoid The spinal accessory nerve supplies the Sternocleidomastoid and trapezius Option B. Levator scapulae Levator scapulae are supplied by the Dorsal scapular nerve Option D. Trapezius The spinal accessory nerve supplies the Sternocleidomastoid and trapezius</p>\n<p><strong>Extraedge:</strong></p><p>The accessory nerve is tested by evaluating the function of the trapezius and sternocleidomastoid muscles. The trapezius muscle is tested by asking the patient to shrug their shoulders with and without resistance. The sternocleidomastoid muscle is tested by asking the patient to turn their head to the left or right against resistance.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the vagus nerve in the following diagram:", "options": [{"label": "A", "text": "A", "correct": true}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "С", "correct": false}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "A. A", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681311573-QTDA023003IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A A- vagus nerve B- sympathetic chain C- spinal nerve D- recurrent laryngeal nerve Transverse section showing layers of Deep cervical fascia</p>\n<p><strong>Highyeild:</strong></p><p>The deep cervical fascia is often divided into a superficial, middle, and deep layer. The superficial layer is also known as the investing layer of deep cervical fascia . It envelops the trapezius, sternocleidomastoid, and muscles of facial expression. It also contains the submandibular and parotid salivary glands as well as the muscles of mastication (the masseter, pterygoid, and temporalis muscles). The middle layer is also known as the pretracheal fascia. It envelopes the strap muscles (sternohyoid, sternothyroid, thyrohyoid, and omohyoid muscles). It also surrounds the pharynx, larynx, trachea, esophagus, thyroid, parathyroids, buccinators, and constrictor muscles of the pharynx. The deep layer is also known as the prevertebral fascia. It surrounds the paraspinous muscles and cervical vertebrae.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. B B- sympathetic chain Option C. С C- spinal nerve Option D. D D- recurrent laryngeal nerve</p>\n<p><strong>Extraedge:</strong></p><p>The carotid sheath is also considered a component of the deep cervical fascia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The genioglossus is a fan-shaped muscle that is involved in forming most of the tongue mass if there is palsy of the right- genioglossus it it will deviate the tongue towards", "options": [{"label": "A", "text": "Deviation of the tongue to the right side", "correct": true}, {"label": "B", "text": "Deviation of the tongue to the left side", "correct": false}, {"label": "C", "text": "Deviation of the soft palate to the right side", "correct": false}, {"label": "D", "text": "Deviation of the soft palate to the left side", "correct": false}], "correct_answer": "A. Deviation of the tongue to the right side", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deviation of the tongue to the right side The protruded tongue deviates to the same side of the lesion, due to the unopposed action of muscle on the normal side when the patient is asked to protrude the tongue.</p>\n<p><strong>Highyeild:</strong></p><p>Genioglossus is the only muscle of the tongue which protrudes forwards. It is used for testing the integrity of the hypoglossal nerve. If the hypoglossal nerve of the right side is paralyzed, the tongue on protrusion will deviate to the right side. Normal left genioglossus will pull the base to the left side and the apex will get pushed to the right side (apex and base lie at opposite ends)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Deviation of the tongue to the left side If the hypoglossal nerve of the right side is paralyzed, the tongue on protrusion will deviate to the right side. Normal left genioglossus will pull the base to the left side and the apex will get pushed to the right side (apex and base lie at opposite ends). Option C. Deviation of the soft palate to the right side If the hypoglossal nerve of the right side is paralyzed, the tongue on protrusion will deviate to the right side. Normal left genioglossus will pull the base to the left side and the apex will get pushed to the right side (apex and base lie at opposite ends). Option D. Deviation of the soft palate to the left side If the hypoglossal nerve of the right side is paralyzed, the tongue on protrusion will deviate to the right side. Normal left genioglossus will pull the base to the left side and the apex will get pushed to the right side (apex and base lie at opposite ends).</p>\n<p><strong>Extraedge:</strong></p><p>Genioglossus is called the ‘safety muscle of the tongue ’ because if it is paralyzed, the tongue will fall back on the oropharynx and block the air passage. During anaesthesia, the tongue is pulled forwards to clear the air passage.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Muscles of the tongue are supplied by:", "options": [{"label": "A", "text": "Lingual Nerve", "correct": false}, {"label": "B", "text": "Glossopharyngeal nerve", "correct": false}, {"label": "C", "text": "Chorda tympani", "correct": false}, {"label": "D", "text": "Hypoglossal nerve", "correct": true}], "correct_answer": "D. Hypoglossal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Hypoglossal nerve Motor Nerves All the intrinsic and extrinsic muscles, except the palatoglossus, are supplied by the hypoglossal nerve.</p>\n<p><strong>Highyeild:</strong></p><p>The palatoglossus is supplied by the cranial root of the accessory nerve through the pharyngeal plexus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Lingual Nerve The lingual nerve is the nerve of general sensation and the chorda tympani is the nerve of taste for the anterior two-thirds of the tongue except vallate papillae. Glossopharyngeal nerve The glossopharyngeal nerve is the nerve for both general sensation and taste for the posterior one-third of the tongue including the circumvallate papillae. Chorda tympani The lingual nerve is the nerve of general sensation and the chorda tympani is the nerve of taste for the anterior two-thirds of the tongue except vallate papillae.</p>\n<p><strong>Extraedge:</strong></p><p>Sensory Innervation of Tongue The lingual nerve is the nerve of general sensation and the chorda tympani is the nerve of taste for the anterior two-thirds of the tongue except vallate papillae. The glossopharyngeal nerve is the nerve for both general sensation and taste for the posterior one-third of the tongue including the circumvallate papillae. The posterior-most part of the tongue is supplied by the vagus nerve through the internal laryngeal branch.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Safety muscle of the tongue is:", "options": [{"label": "A", "text": "Hyoglossus", "correct": false}, {"label": "B", "text": "Genioglossus", "correct": true}, {"label": "C", "text": "Palatoglossus", "correct": false}, {"label": "D", "text": "Styloglossus", "correct": false}], "correct_answer": "B. Genioglossus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Genioglossus Genioglossus is called the ‘safety muscle of the tongue’ because if it is paralyzed, the tongue will fall back on the oropharynx and block the air passage. During anaesthesia, the tongue is pulled forwards to clear the air passage.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Hyoglossus Genioglossus is called the ‘safety muscle of the tongue’ because if it is paralyzed, the tongue will fall back on the oropharynx and block the air passage. During anaesthesia, the tongue is pulled forwards to clear the air passage. Option C. Palatoglossus Genioglossus is called the ‘safety muscle of the tongue’ because if it is paralyzed, the tongue will fall back on the oropharynx and block the air passage. During anaesthesia, the tongue is pulled forwards to clear the air passage. Option D. Styloglossus Genioglossus is called the ‘safety muscle of the tongue’ because if it is paralyzed, the tongue will fall back on the oropharynx and block the air passage. During anaesthesia, the tongue is pulled forwards to clear the air passage.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The sensory supply to the palate is through all of the following, except:", "options": [{"label": "A", "text": "Facial Nerve", "correct": false}, {"label": "B", "text": "Hypoglossal nerve", "correct": true}, {"label": "C", "text": "Glossopharyngeal nerve", "correct": false}, {"label": "D", "text": "Maxillary division of trigeminal nerve", "correct": false}], "correct_answer": "B. Hypoglossal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Hypoglossal nerve The hypoglossal nerve supplies the muscles of the tongue.</p>\n<p><strong>Highyeild:</strong></p><p>Origin, insertion, and actions of the muscle of the soft palate Muscle Origin Insertion Actions Tensor palati (thin triangular muscle; Fig. 14.22) (a) Lateral aspect of the cartilaginous part of the auditory tube(b) Adjoining part of the greater wing of the sphenoid including its spine Muscle descends, converges to form a tendon, which hooks around the pterygoid hamulus and then expands to form the palatine aponeurosis for attachment to:• Posterior border of the hard palate• Inferior surface of the hard palate behind the palatine crest (a) Tightens the soft palate(b) Helps in opening the auditory tube Levator palati(a cylindrical muscle lying deep to tensor palati) (a) Medial aspect of the cartilaginous part of the auditory tube(b) Adjoining part of the petrous temporal bone (inferior surface of its apex anterior to carotid canal) Muscle runs downwards and medially and spreads out to be inserted on the upper surface of the palatine aponeurosis (a) Elevates the soft palate to close the pharyngeal isthmus(b) Helps in opening the auditory tube Musculus uvulae(a longitudinal musclestrip, one on either side of the median plane withinthe palatine aponeurosis) a) Posterior nasal spineb) Palatine aponeurosis Mucous membrane of the uvula Pulls the uvula forward to its own side Palatoglossus Oral surface of the palatine aponeurosis Descends into palatoglossal arch, to be inserted into the side of the tongue at the junction of its oral and pharyngeal parts (a) Pulls up the root of the tongue(b) Approximates the palatoglossal arches to close the oropharyngeal isthmus Palatopharyngeus (consist of two fasciculi, which are separated by the levator palati) (a) Anterior fasciculus: from posterior border of the hard palate(b) Posterior fasciculus: from palatine aponeurosis Descends in the palatopharyngeal arch and inserted into the• Median fibrous raphe ofpharyngeal wall• Posterior border of the lamina of thyroid cartilage Raises the walls of pharynx and larynx during swallowing</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Facial Nerve Option Glossopharyngeal nerve Option D. Maxillary division of trigeminal nerve Facial nerves, glossopharyngeal nerves and palatine branches convey general and special sensations to the</p>\n<p><strong>Extraedge:</strong></p><p>The hard palate is supplied by greater palatine and nasopalatine nerves derived from the pterygopalatine ganglion. The greater palatine nerve supplies the whole of the palate except the anterior part of the palate behind the incisor teeth (the area of the premaxilla), which is supplied by nasopalatine nerves.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 54-year-old man is admitted to the hospital due to a severe headache. A CT examination reveals an internal carotid artery aneurysm inside the cavernous sinus. Which of the following nerves would be typically affected first?", "options": [{"label": "A", "text": "Abducens Nerve", "correct": true}, {"label": "B", "text": "Oculomotor nerve", "correct": false}, {"label": "C", "text": "Ophthalmic nerve", "correct": false}, {"label": "D", "text": "Maxillary nerve", "correct": false}], "correct_answer": "A. Abducens Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Abducens Nerve The abducens nerve would be affected first due to aneurysmal dilation of the internal carotid artery (ICA) because the nerve runs in closest proximity to the artery within the cavernous sinus. Structures passing through each cavernous sinus are: The internal carotid artery, and the abducens nerve [VI]. Cavernous sinus</p>\n<p><strong>Highyeild:</strong></p><p>Structures in the lateral wall of each cavernous sinus are, from superior to inferior: the oculomotor nerve [III] the trochlear nerve [IV] the ophthalmic nerve [V1], and the maxillary nerve [V2].</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options B, C, D: The other nerves running in the wall of the cavernous sinus are the oculomotor nerve, trochlear nerve, and both the maxillary and ophthalmic branches of the trigeminal nerve. Each of these nerves, however, courses along, or within, the lateral walls of the cavernous sinus and may not be immediately affected by an aneurysm of the ICA</p>\n<p><strong>Extraedge:</strong></p><p>The superior sagittal and straight sinuses, and the occipital sinus (in the falx cerebelli) empty into the confluence of sinuses, which is a dilated space at the internal occipital protuberance and is drained by the right and left transverse sinuses.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A tonsillectomy is performed and the patient complains postoperatively of ear pain. Which of the following nerves was most likely injured during the surgical procedure?", "options": [{"label": "A", "text": "Auriculotemporal", "correct": false}, {"label": "B", "text": "Lesser petrosal", "correct": false}, {"label": "C", "text": "Vagus", "correct": false}, {"label": "D", "text": "Glossopharyngeal", "correct": true}], "correct_answer": "D. Glossopharyngeal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Glossopharyngeal The glossopharyngeal nerve mediates general somatic sensation from the pharynx, the auditory tube, and the middle ear. Painful sensations from the pharynx, including the auditory tube, can be referred to the ear by this nerve, as in the case of tonsillectomy.</p>\n<p><strong>Highyeild:</strong></p><p>The upper two-thirds of the lateral surface of the auricle are supplied by the auriculotemporal nerve; the lower one-third by the great auricular nerve. The upper two-thirds of the medial surface is supplied by the lesser occipital nerve, and the lower one-third by the great auricular nerve. The root of the auricle is supplied by the auricular branch of the vagus. The auricular muscles are supplied through branches of the facial nerve. Pinna of the ear: (a) Nerve supply and lymph nodes on the lateral surface, and (b) nerve supply on the medial surface</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. The auriculotemporal nerve supplies the skin of the auricle and tympanic membrane and scalp. This nerve would not be involved directly or indirectly in the operation. Option B. The lesser petrosal nerve contains preganglionic parasympathetic fibres that run in the glossopharyngeal and tympanic nerves before synapsing into the otic ganglion. Option C. The vagus nerve mediates general somatic afferent supply to the auricle and external acoustic meatus; stimulation of the meatus can trigger a gag reflex or coughing reflex.</p>\n<p><strong>Extraedge:</strong></p><p>Reasons of earache</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A tonsillectomy is performed on a 17-year-old girl for the complaints of recurrent episodes of tonsillitis and the tonsils are removed. On physical examination 1 week later the patient has an absence of the gag reflex on the left. The sensory portion of which of the following nerves was most likely injured?", "options": [{"label": "A", "text": "Facial", "correct": false}, {"label": "B", "text": "Glossopharyngeal", "correct": true}, {"label": "C", "text": "Mandibular", "correct": false}, {"label": "D", "text": "Maxillary", "correct": false}], "correct_answer": "B. Glossopharyngeal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Glossopharyngeal The gag reflex is composed of both an afferent and an efferent limb. These reflexes are mediated by the glossopharyngeal and vagus nerves, respectively. Together, the glossopharyngeal and vagus nerves are responsible for the contraction of the muscles of the pharynx involved in the gag reflex. In this case, the glossopharyngeal nerve was injured when the tonsils were excised, resulting in the loss of the sensory side of the reflex.</p>\n<p><strong>Highyeild:</strong></p><p>Cranial nerve reflexes Corneal (blink) reflex Pupillary (light) reflex Afferent-Trigeminal nerve (CNV) Efferent-Facial nerve (CN VII) nGag reflex Afferent-Glossopharyngeal nerve (CN IX) Efferent-Vagus nerve (CNX) Afferent-optic nerve (CN II) Efferent-oculomotor nerve (CN III)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. The facial nerve is involved with a taste of the anterior two-thirds of the tongue; however, it does not mediate the gag reflex. Option C, D. The mandibular and maxillary nerves are part of the trigeminal nerve and are thus largely associated with the sensory supply of the face, sinuses, and oral cavity</p>\n<p><strong>Extraedge:</strong></p><p>The gag reflex is a natural somatic response in which the body attempts to eliminate unwanted agents or foreign objects from the oral cavity through muscle contraction at the base of the tongue and the pharyngeal wall.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 32-year-old woman underwent a thyroidectomy. Two months postoperatively, it was observed that the patient had lost the ability to notice the presence of foreign objects in the laryngeal vestibule. Which of the following nerves was most likely injured?", "options": [{"label": "A", "text": "Internal Laryngeal Nerve", "correct": true}, {"label": "B", "text": "External laryngeal nerve", "correct": false}, {"label": "C", "text": "Glossopharyngeal nerve", "correct": false}, {"label": "D", "text": "Hypoglossal nerve", "correct": false}], "correct_answer": "A. Internal Laryngeal Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Internal Laryngeal Nerve Damage to the internal laryngeal nerve would result in a general loss of sensation to the larynx above the vocal cords, leaving the patient with an inability to detect food or foreign objects in the laryngeal vestibule.</p>\n<p><strong>Highyeild:</strong></p><p>Superior laryngeal nerves The superior laryngeal nerves originate from the inferior vagal ganglia high in the neck. On each side, the nerve descends medial to the internal carotid artery and divides into internal and external branches just above the level of the superior horn of the hyoid bone: The external branch (external laryngeal nerve) descends along the lateral wall of the pharynx to supply and penetrate the inferior constrictor of the pharynx and ends by supplying the cricothyroid muscle. The internal branch (internal laryngeal nerve) passes anteroinferiorly to penetrate the thyrohyoid membrane-it is mainly sensory and supplies the laryngeal cavity down to the level of the vocal folds. Nerve supply of larynx</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options B, C. The external laryngeal nerve and recurrent laryngeal nerve are both at risk during thyroidectomy. Damage to the recurrent laryngeal nerve would result in paralysis of all the laryngeal muscles except the cricothyroid; it would render the patient hoarse, with a loss of sensation below the vocal cords. Loss of the external laryngeal nerve would lead to paralysis of the cricothyroid muscle and vocal weakness. Option D. Injury to the hypoglossal nerve would result in weakness or paralysis of muscle movement of the tongue.</p>\n<p><strong>Extraedge:</strong></p><p>Recurrent laryngeal nerves The recurrent laryngeal nerves are : Sensory to the laryngeal cavity below the level of the vocal folds, and Motor to all intrinsic muscles of the larynx except for the cricothyroid.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 55-year-old man suffers from odynophagia and hoarseness in his speech. Radiographic examination reveals a tumour at the tracheoesophageal groove. Which of the following nerves is most likely affected by the tumour?", "options": [{"label": "A", "text": "Recurrent Laryngeal", "correct": true}, {"label": "B", "text": "Internal laryngeal", "correct": false}, {"label": "C", "text": "Vagus", "correct": false}, {"label": "D", "text": "External laryngeal", "correct": false}], "correct_answer": "A. Recurrent Laryngeal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Recurrent Laryngeal The right and left recurrent laryngeal nerves loop around the right subclavian artery and the arch of the aorta, respectively. These nerves then travel superiorly in the tracheoesophageal groove to the larynx. Damage to the recurrent laryngeal nerve as a result of surgical intervention or the presence of a tumour in the tracheoesophageal groove would render the patient hoarse. This hoarseness is due to a lack of innervation by the recurrent laryngeal nerve to most of the muscles of the larynx. Recurrent laryngeal nerve</p>\n<p><strong>Highyeild:</strong></p><p>The vagus nerves, from which the recurrent laryngeal nerves branch, exit the skull at the jugular foramen and travel within the carotid sheath alongside the carotid arteries through the neck. The recurrent laryngeal nerves branch off the vagus, the left at the aortic arch, and the right at the right subclavian artery. The left RLN passes in front of the arch, and then wraps underneath and behind it. After branching, the nerves typically ascend in a groove at the junction of the trachea and esophagus. They then pass behind the posterior, middle part of the outer lobes of the thyroid gland and enter the larynx underneath the inferior constrictor muscle, passing into the larynx just posterior to the cricothyroid joint.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Damage to the internal laryngeal nerve would cause a loss of sensation above the vocal cords, in addition to a loss of taste on the epiglottis. Option C. The vagus nerve gives rise to the recurrent laryngeal nerves; damage to this nerve, however, would result in numerous symptoms beyond just hoarseness. Option D. Damage to the external laryngeal nerve, which can occur during thyroidectomy, will result in a loss of innervation to the cricothyroid muscle, with resultant vocal weakness. Patients with this lesion will often present with a fatigued voice.</p>\n<p><strong>Extraedge:</strong></p><p>Unlike the other nerves supplying the larynx, the right and left RLNs lack bilateral symmetry. The left RLN is longer than the right because it crosses under the arch of the aorta at the ligamentum arteriosum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 62-year-old man is complaining of dysphagia and dysarthria. An MRI showed a tumour of the brainstem affecting the contents of the hypoglossal canal. Which of the following muscles would be affected by such a tumour?", "options": [{"label": "A", "text": "Geniohyoid", "correct": false}, {"label": "B", "text": "Mylohyoid", "correct": false}, {"label": "C", "text": "Palatoglossus", "correct": false}, {"label": "D", "text": "Genioglossus", "correct": true}], "correct_answer": "D. Genioglossus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Genioglossus The hypoglossal nerve (CN XII) passes through the hypoglossal canal. All the muscles of the tongue, intrinsic and extrinsic, are supplied by the hypoglossal nerve (except palatoglossus). Innervation of Tongue</p>\n<p><strong>Highyeild:</strong></p><p>Veins from the palate generally follow the arteries and ultimately drain into the pterygoid plexus of veins in the infra temporal fossa, or into a network of veins associated with the palatine tonsil, which drain into the pharyngeal plexus of veins or directly into the facial vein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Geniohyoid is a strap muscle Option B. Mylohyoid is supplied by the inferior alveolar nerve, a branch of the mandibular nerve Option C. Palatoglossus is supplied by the spinal accessory nerve through the pharyngeal plexus.</p>\n<p><strong>Extraedge:</strong></p><p>Lymphatic vessels from the palate drain into deep cervical nodes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 23 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Lateral most content of cubital fossa:", "options": [{"label": "A", "text": "Biceps Tendon", "correct": false}, {"label": "B", "text": "Radial nerve", "correct": true}, {"label": "C", "text": "Brachial artery", "correct": false}, {"label": "D", "text": "Median nerve", "correct": false}], "correct_answer": "B. Radial nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Radial nerve Cubital Fossa</p>\n<p><strong>Highyeild:</strong></p><p>Content from medial to lateral (mnemonic – MBBR) Median Nerve Brachial Artery Biceps Tendon Radial Nerve</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Supracondylar Fracture may lead to posterior displacement of the distal fragment of humerus as well as the radius and ulna. The contents of the cubital fossa are compromised specifically the median nerve and brachial artery. Volkmann contracture is an ischemic muscular contracture (flexion deformity) of the fingers and sometimes of the wrist, resulting from reduced blood flow and necrosis of the forearm flexor muscles, caused by a pressure injury, such as compartment syndrome, or a tight cast. The muscles are replaced by fibrous tissue, which contracts, producing the flexion deformity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The lateral boundary of the cubital fossa is formed by:", "options": [{"label": "A", "text": "Medial border of pronator teres", "correct": false}, {"label": "B", "text": "Lateral border of pronator teres", "correct": false}, {"label": "C", "text": "Medial border of brachioradialis", "correct": true}, {"label": "D", "text": "Lateral border of brachioradialis", "correct": false}], "correct_answer": "C. Medial border of brachioradialis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Medial border of brachioradialis Cubital Fossa Boundaries Lateral boundary – Medial border of brachioradialis Medial boundary – Lateral border of pronator teres Base – It is directed upwards, and is represented by an imaginary line joining the front of two epicondyles of the humerus. Apex – It is directed downwards, and is formed by the area where the brachioradialis crosses the pronator teres muscle.</p>\n<p><strong>Highyeild:</strong></p><p>Content from medial to lateral (mnemonic – MBBR) Median Nerve Brachial Artery Biceps Tendon Radial Nerve</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Supracondylar Fracture may lead to posterior displacement of the distal fragment of humerus as well as the radius and ulna. The contents of the cubital fossa are compromised specifically the median nerve and brachial artery. Volkmann contracture is an ischemic muscular contracture (flexion deformity) of the fingers and sometimes of the wrist, resulting from reduced blood flow and necrosis of the forearm flexor muscles, caused by a pressure injury, such as compartment syndrome, or a tight cast. The muscles are replaced by fibrous tissue, which contracts, producing the flexion deformity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following muscles have a dual nerve supply, except:", "options": [{"label": "A", "text": "Subscapularis", "correct": false}, {"label": "B", "text": "Pectoralis major", "correct": false}, {"label": "C", "text": "Pronator teres", "correct": true}, {"label": "D", "text": "Flexor digitorum profundus", "correct": false}], "correct_answer": "C. Pronator teres", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pronator teres Pronator teres are not a hybrid muscle and are supplied by the median nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Content from medial to lateral (mnemonic – MBBR) Median Nerve Brachial Artery Biceps Tendon Radial Nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Subscapularis Subscapularis muscle: Upper subscapular nerve and lower subscapular nerve Option: B. Pectoralis major Pectoralis major - Lateral pectoral nerve and medial pectoral nerve Option: D. Flexor digitorum profundus Flexor digitorum profundus – median nerve and ulnar nerve</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Supracondylar Fracture may lead to posterior displacement of the distal fragment of humerus as well as the radius and ulna. The contents of the cubital fossa are compromised specifically the median nerve and brachial artery. Volkmann contracture is an ischemic muscular contracture (flexion deformity) of the fingers and sometimes of the wrist, resulting from reduced blood flow and necrosis of the forearm flexor muscles, caused by a pressure injury, such as compartment syndrome, or a tight cast. The muscles are replaced by fibrous tissue, which contracts, producing the flexion deformity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Bicipital aponeurosis lies over which structure in the cubital fossa?", "options": [{"label": "A", "text": "Median Cubital Vein", "correct": false}, {"label": "B", "text": "Radial nerve", "correct": false}, {"label": "C", "text": "Brachial artery", "correct": true}, {"label": "D", "text": "Anterior interosseous artery", "correct": false}], "correct_answer": "C. Brachial artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Brachial artery The bicipital aponeurosis is derived from the biceps tendon & passes superficial to the brachial artery and median nerve. It lies deep in superficial veins Bicipital Aponeurosis</p>\n<p><strong>Highyeild:</strong></p><p>Content from medial to lateral (mnemonic – MBBR) Median Nerve Brachial Artery Biceps Tendon Radial Nerve</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Supracondylar Fracture may lead to posterior displacement of the distal fragment of humerus as well as the radius and ulna. The contents of the cubital fossa are compromised specifically the median nerve and brachial artery. Volkmann contracture is an ischemic muscular contracture (flexion deformity) of the fingers and sometimes of the wrist, resulting from reduced blood flow and necrosis of the forearm flexor muscles, caused by a pressure injury, such as compartment syndrome, or a tight cast. The muscles are replaced by fibrous tissue, which contracts, producing the flexion deformity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The brachial artery was found to be blocked during angiography of the upper limb arteries. Blood flow will be reduced in all of the following vessels, except:", "options": [{"label": "A", "text": "Profunda Brachii artery", "correct": false}, {"label": "B", "text": "The superior ulnar collateral artery", "correct": false}, {"label": "C", "text": "The inferior ulnar collateral artery", "correct": false}, {"label": "D", "text": "The anterior circumflex humeral artery", "correct": true}], "correct_answer": "D. The anterior circumflex humeral artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The anterior circumflex humeral artery The anterior circumflex humeral artery The anterior circumflex humeral artery will have a normal blood supply in this case. The axillary artery, not the brachial artery, is the source of the anterior circumflex humeral artery.</p>\n<p><strong>Highyeild:</strong></p><p>Content from medial to lateral (mnemonic – MBBR) Median Nerve Brachial Artery Biceps Tendon Radial Nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Profunda Brachii artery Option: B. The superior ulnar collateral artery Option: C. The inferior ulnar collateral artery Branches of Brachial artery Profunda brachii, Superior ulnar collateral, and Inferior ulnar collateral arteries are branches of the Brachial artery.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Supracondylar Fracture may lead to posterior displacement of the distal fragment of humerus as well as the radius and ulna. The contents of the cubital fossa are compromised specifically the median nerve and brachial artery. Volkmann contracture is an ischemic muscular contracture (flexion deformity) of the fingers and sometimes of the wrist, resulting from reduced blood flow and necrosis of the forearm flexor muscles, caused by a pressure injury, such as compartment syndrome, or a tight cast. The muscles are replaced by fibrous tissue, which contracts, producing the flexion deformity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You've been asked to send a blood sample for a clinically significant full-blood count study. Which of the following veins should be used for sampling?", "options": [{"label": "A", "text": "The cephalic vein", "correct": false}, {"label": "B", "text": "Antecubital vein", "correct": true}, {"label": "C", "text": "Basilic vein", "correct": false}, {"label": "D", "text": "Brachial vein", "correct": false}], "correct_answer": "B. Antecubital vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Antecubital vein The concept for Correct Option- For direct blood investigations, the antecubital vein (median cubital vein) is typically the vein of choice. Antecubital Vein At the roof of the cubital fossa, the median cubital vein connects the cephalic vein with the basilic vein. It is easily accessible because it lies superficial to the bicipital aponeurosis. It is used for IV injections, blood transfusions, and blood withdrawal.</p>\n<p><strong>Highyeild:</strong></p><p>Content from medial to lateral (mnemonic – MBBR) Median Nerve Brachial Artery Biceps Tendon Radial Nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The cephalic vein, which begins as a radial extension of the dorsal venous arch and travels over the roof of the anatomical snuffbox, is a radial continuation of the dorsal venous arch. It comes to an end in the axillary vein. The median cubital vein connects it to the basilic vein. It's the best place to put a short-term IV cannula. Option: C. The basilic vein passes through the medial portion of the forearm , draining the ulnar end of the dorsal venous arch. At the lower boundary of the teres major, it pierces the deep fascia at the elbow and joins the venue commutants of the brachial artery to produce the axillary vein. Option: D. The brachial vein is a deep forearm vein that runs parallel to the brachial artery on both sides. It is generated by connecting the radial and ulnar arteries at their junctions. At the lower boundary of the teres major, it connects the axillary vein.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Supracondylar Fracture may lead to posterior displacement of the distal fragment of humerus as well as the radius and ulna. The contents of the cubital fossa are compromised specifically the median nerve and brachial artery. Volkmann contracture is an ischemic muscular contracture (flexion deformity) of the fingers and sometimes of the wrist, resulting from reduced blood flow and necrosis of the forearm flexor muscles, caused by a pressure injury, such as compartment syndrome, or a tight cast. The muscles are replaced by fibrous tissue, which contracts, producing the flexion deformity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "During your D-Hall viva, the following dissection was shown by the professor. Which of the following muscles is not supplied by the nerve shown?", "options": [{"label": "A", "text": "Thyrohyoid", "correct": true}, {"label": "B", "text": "Sternothyroid", "correct": false}, {"label": "C", "text": "Sternohyoid", "correct": false}, {"label": "D", "text": "Inferior belly of omohyoid", "correct": false}], "correct_answer": "A. Thyrohyoid", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681336914-QTDA024001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thyrohyoid The marked structure is ansa cervicalis and thyrohyoid is not supplied by it. Thyrohyoid is supplied by the C1 fibres through the hypoglossal nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Ansa cervicalis The ansa cervicalis (ansa hypoglossi) is a U-shaped nerve loop present in the region of the carotid triangle embedded in the anterior wall of the carotid sheath. It is derived from the ventral rami of the C1, C2, and C3 spinal nerves. It supplies all the infrahyoid muscles except thyrohyoid, which is supplied by the nerve to thyrohyoid (C1) from the hypoglossal nerve. ; Roots: Ansa cervicalis has the following two roots The superior root (descendens hypoglossi) is formed by the descending branch of the hypoglossal nerve carrying C1 spinal nerve fibres. It descends downwards over internal and common carotid arteries. The inferior root (descendens cervicalis) is derived from C2 and C3 spinal nerves. As this root descends, it first winds around the internal jugular vein and then continues anteroinferiorly to join the superior root in front of the common carotid artery at the level of the cricoid cartilage. Formation and distribution of the ansa cervicalis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Sternothyroid Option C. Sternohyoid Option D. Inferior belly of omohyoid All the muscles mentioned in options B, C and D are innervated by Ansa Cervicalis. The muscles supplied by ansa cervicalis are: The superior root gives a branch to the superior belly of the omohyoid. The dependent loop gives branches to the sternohyoid, sternothyroid, and inferior belly of the omohyoid.</p>\n<p><strong>Extraedge:</strong></p><p>Distribution of Ansa Cervicalis roots. The superior root gives a branch to the superior belly of the omohyoid. The dependent loop gives branches to the sternohyoid, sternothyroid, and inferior belly of the omohyoid.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "While performing a modified radical neck dissection, the surgeon damages the structure marked below on one side. It was noted that the patient had trouble during the shrugging of the right shoulder. Which of the following is supplied by this structure?", "options": [{"label": "A", "text": "Diaphragm", "correct": false}, {"label": "B", "text": "Trapezius", "correct": true}, {"label": "C", "text": "Skin over parotid gland", "correct": false}, {"label": "D", "text": "Supraspinatus", "correct": false}], "correct_answer": "B. Trapezius", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681336977-QTDA024002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Trapezius The structure marked above is the spinal accessory nerve. The spinal accessory nerve enters the posterior triangle passing deep to the sternocleidomastoid muscle and runs in an oblique direction within the triangle to supply the trapezius.</p>\n<p><strong>Highyeild:</strong></p><p>The fibres that form the spinal accessory nerve are formed by lower motor neurons located in the upper segments of the spinal cord. This cluster of neurons called the spinal accessory nucleus , is located in the lateral aspect of the anterior horn of the spinal cord, and stretches from where the spinal cord begins (at the junction with the medulla) through to the level of about C6. The lateral horn of high cervical segments appears to be continuous with the nucleus ambiguous of the medulla oblongata, from which the cranial component of the accessory nerve is derived.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A: Phrenic nerve is seen as related to the anterior surface of the scalenus anterior, and supplies the diaphragm. Option C. The greater auricular nerve supplies the skin over the angle of the jaw, skin over the mandible, and lower 1/3rd of the ear lobule. greater auricular nerve (C2,3) Option D. The suprascapular nerve (C5, C6) arises from the upper trunk of the brachial plexus. It supplies the supraspinatus and infraspinatus muscles</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Note: M There are three types of modified radical neck dissection (MRND). The structures preserved are: MRND 1- Only spinal accessory nerve MRND 2- Accessory nerve and internal jugular vein MRND 3 - i.e functional neck dissection - Accessory nerve, sternocleidomastoid, and internal jugular veins</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You are examining a postoperative patient of a 70-year-old man who underwent a hemiglossectomy for carcinoma of the tongue. During the procedure, posterior triangle lymph nodes were found to be enlarged and all of them were removed. You now suspect that a nerve has been injured while doing the procedure. Which of the following movements will you expect to be intact?", "options": [{"label": "A", "text": "Shrugging of Shoulder", "correct": false}, {"label": "B", "text": "Retraction of scapula", "correct": false}, {"label": "C", "text": "Adduction of arm", "correct": true}, {"label": "D", "text": "Overhead abduction", "correct": false}], "correct_answer": "C. Adduction of arm", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Adduction of arm In the given scenario, the patient most likely suffered an iatrogenic injury to the spinal accessory nerve as it is placed superficially in the middle of the posterior triangle, therefore the actions of the trapezius and sternocleidomastoid can be affected. Adduction of the arm will be intact here, as this action is caused by pectoralis major which is supplied by the medial and lateral pectoral nerves.</p>\n<p><strong>Highyeild:</strong></p><p>Injury to the spinal accessory nerve affects the movements of the muscles supplied by it. They are: Trapezius - overhead abduction, elevation, and retraction of scapula. It is tested by asking the patient to shrug their Stemocleidomastoid- turning the chin to the opposite side, tilting the head towards the shoulder of the same side. When both act together they draw the head forwards.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Shrugging of Shoulder Injury to the spinal accessory nerve affects the movements of the muscles supplied by it. Trapezius - overhead abduction, elevation, and retraction of scapula. It is tested by asking the patient to shrug his Stemocleidomastoid- turning the chin to the opposite side, tilting the head towards the shoulder of the same side. When both act together they draw the head forwards. Option B. Retraction of scapula Injury to the spinal accessory nerve affects the movements of the muscles supplied by it. Trapezius - overhead abduction, elevation, and retraction of scapula. It is tested by asking the patient to shrug his Stemocleidomastoid- turning the chin to the opposite side, tilting the head towards the shoulder of the same side. When both act together they draw the head forwards. Option D. Overhead abduction Injury to the spinal accessory nerve affects the movements of the muscles supplied by it. Trapezius - overhead abduction, elevation, and retraction of scapula. It is tested by asking the patient to shrug his Stemocleidomastoid- turning the chin to the opposite side, tilting the head towards the shoulder of the same side. When both act together they draw the head forwards.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Note: The spinal accessory nerve innervates the sternocleidomastoid just before entering the posterior triangle. If the nerve is injured before it enters the posterior triangle, the actions of the sternocleidomastoid will be affected. If the nerve is injured within the posterior triangle. the sternocleidomastoid will be spared.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "While operating on a case, the surgeon plans to perform radical neck dissection, starting from the anterior triangle. You were present as an intern in the OT and were asked which of the following will the surgeon not dissect?", "options": [{"label": "A", "text": "Subclavian Triangle", "correct": true}, {"label": "B", "text": "Submental triangle", "correct": false}, {"label": "C", "text": "Digastric triangle", "correct": false}, {"label": "D", "text": "Carotid triangle", "correct": false}], "correct_answer": "A. Subclavian Triangle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Subclavian Triangle The subclavian triangle is a posterior triangle of the neck. Posterior triangles in the neck are occipital and subclavian triangles.</p>\n<p><strong>Highyeild:</strong></p><p>The posterior triangle is subdivided into two parts by the inferior belly of the omohyoid, which crosses the lower part of the triangle obliquely upwards and forwards. (a) a larger upper part called the occipital triangle, and(b) a small lower part called the subclavian (supraclavicular) triangle. These parts are so named because they contain occipital and subclavian arteries, respectively. Posterior Triangle of Neck</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options B, C & D are the triangle content of the anterior triangle. The anterior triangle consists is consist of the following triangles: Submental triangle Digastric triangle Muscular triangle Carotid triangle</p>\n<p><strong>Extraedge:</strong></p><p>For the convenience of description, the anterior triangle has been subdivided, by the digastric muscle and superior belly of the omohyoid muscle, into the following 31⁄2 triangles. Submental triangle (half only). Digastric (submandibular) triangle. Carotid triangle. Muscular triangle Boundaries and subdivisions of the right anterior triangle</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were attending a CME on Head and Neck Surgery for free attendance. Your professor during the D- Hall asked about the topic of Neck Triangles that was discussed and how its knowledge can help avoid iatrogenic injuries during surgery. The occipital triangle contains all of the following Except:", "options": [{"label": "A", "text": "Great Auricular Nerve", "correct": false}, {"label": "B", "text": "Lesser occipital nerve", "correct": false}, {"label": "C", "text": "Occipital artery", "correct": false}, {"label": "D", "text": "Suprascapular nerve", "correct": true}], "correct_answer": "D. Suprascapular nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Suprascapular nerve The suprascapular nerve is a branch from the upper trunk of the brachial plexus and is a content of the subclavian part of the posterior triangle, not the occipital triangle.</p>\n<p><strong>Highyeild:</strong></p><p>Content of Occipital Triangle Spinal accessory nerve 3rd and 4th cervical nerves provide branches to levator scapulae and trapezius muscles Dorsal scapular nerve(C5) Four cutaneous branches of the cervical plexus: The lesser occipital nerve The great auricular nerve The transverse cervical nerve. The supraclavicular nerves (e) Superficial transverse cervical artery. (f) Occipital artery. Content of Posterior Triangle</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Great Auricular Nerve, Option B. Lesser occipital nerve, Option C. Occipital arteries all are content of occipital triangle.</p>\n<p><strong>Extraedge:</strong></p><p>Content of Subclavian/Supraclavicular triangle (below the omohyoid) (a) 3rd part of the subclavian artery (b) Subclavian vein (c) Terminal Part of External Jugular Vein (d) Trunks of brachial plexus (e) Superficial (transverse) cervical, suprascapular, and dorsal scapular arteries (f) Lymph nodes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Below is the pictorial representation of spaces of the neck enclosed by cervical fascia. The spaces are marked as A, B, C, D. Dangerous area of the neck is marked by:", "options": [{"label": "A", "text": "A", "correct": true}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "A. A", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681337007-QTDA024006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A A- the dangerous area of the neck B- prevertebral space C- retropharyngeal space D- pretracheal space Retropharyngeal space lies posterior to the buccopharyngeal fascia. Alar fascia is an ancillary layer of deep cervical fascia which divides retropharyngeal space into two parts. The posterior space between the alar and prevertebral fascia is the ‘dangerous space in the neck’ .</p>\n<p><strong>Highyeild:</strong></p><p>The danger space has no specific contents apart from a small amount of loose fatty connective tissue and is thus usually indistinguishable from the true retropharyngeal space on imaging. Boundaries anteriorly: alar fascia posteriorly: a prevertebral layer of the deep cervical fascia superiorly: clivus inferiorly: posterior mediastinum at the level of the diaphragm It is a potential path for the spread of infections (e.g. retropharyngeal abscess) from the pharynx to the mediastinum.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. B B- prevertebral space Option C. C C- retropharyngeal space Option D. D D- pretracheal space</p>\n<p><strong>Extraedge:</strong></p><p>The retropharyngeal space is a potential space and deep compartment of the head and neck situated posterior to the pharynx. The RPS is bounded anteriorly by the buccopharyngeal fascia, posteriorly by the alar fascia, and laterally by the carotid sheath. It extends between the base of the skull superiorly, and the mediastinum inferiorly. It contains the retropharyngeal lymph nodes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The parotid gland is covered by:", "options": [{"label": "A", "text": "Buccopharyngeal Fascia", "correct": false}, {"label": "B", "text": "Investing layer of deep cervical fascia", "correct": true}, {"label": "C", "text": "Alar fascia", "correct": false}, {"label": "D", "text": "Pretracheal layer", "correct": false}], "correct_answer": "B. Investing layer of deep cervical fascia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Investing layer of deep cervical fascia The investing layer of deep cervical fascia splits to enclose and form: forms roofs of 2 triangles, anterior and posterior triangles. splits to enclose 2 glands, submandibular and parotid. splits to enclose 2 spaces, suprasternal and supraclavicular. forms 2 fascial slings (pulleys) for the inferior belly of the omohyoid and intermediate tendon of the digastric muscle. encloses 2 muscles, trapezius and sternocleidomastoid.</p>\n<p><strong>Highyeild:</strong></p><p>The suprasternal space or space of Burns contains: The sternal heads of the right and left sternocleidomastoid muscles, The jugular venous arch, A lymph node, and The interclavicular ligament.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Buccopharyngeal Fascia Option C. Alar fascia Option D. Pretracheal layer Options A, C and D are incorrect answers because the parotid gland is enclosed by an investing layer of deep cervical fascia.</p>\n<p><strong>Extraedge:</strong></p><p>The supraclavicular space is traversed by: The external jugular vein, The supraclavicular nerves, and Cutaneous vessels, including lymphatics.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The subcutaneous muscle extends from the clavicle to the mandible and covers most of the anterior and lateral aspects of the neck.", "options": [{"label": "A", "text": "Platysma", "correct": true}, {"label": "B", "text": "Sternocleidomastoid", "correct": false}, {"label": "C", "text": "Omohyoid", "correct": false}, {"label": "D", "text": "Sternohyoid", "correct": false}], "correct_answer": "A. Platysma", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Platysma PLATYSMA It is a thin quadrilateral broad sheet of muscle in the superficial fascia of the side of the neck. It ascends onto the face from the front of the neck.</p>\n<p><strong>Highyeild:</strong></p><p>Morphologically Platysma represents the remnant of panniculus Carnosus of animals. It develops from the 2nd pharyngeal arch. It covers the anterior inferior part of the posterior triangle and the superior part of the anterior triangle of the neck.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Sternocleidomastoid Sternocleidomastoid muscle Each is a pair of long muscles which connect the sternum, clavicle, and mastoid process of the temporal bone and serve to turn and nod the neck. Option C. Omohyoid The omohyoid muscle is a long, thin muscle consisting of superior and inferior bellies and an intermediate tendon, which runs obliquely in the lateral cervical region. The omohyoid is important in neck dissections because it is the surgical landmark for level III and IV lymph node metastases. Option D. Sternohyoid The sternohyoid muscle is a flat muscle located on both sides of the neck. This muscle originated from the medial edge of the clavicle bone, sternoclavicular ligament, and posterior side of the manubrium. The sternohyoid muscle then ascends to the neck and attaches to the body of the hyoid bone.</p>\n<p><strong>Extraedge:</strong></p><p>The platysma muscle is a superficial muscle of the human neck that overlaps the sternocleidomastoid. It covers the anterior surface of the neck superficially. When it contracts, it produces a slight wrinkling of the neck and a \"bowstring\" effect on either side of the neck. The platysma muscle is supplied by the cervical branch of the facial nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is true about the superficial layer of the fascia?", "options": [{"label": "A", "text": "Investing layer covers the parotid gland and submandibular gland", "correct": true}, {"label": "B", "text": "Pretracheal layer covers both the thyroid and parotid gland", "correct": false}, {"label": "C", "text": "Axillary sheath is formed by the pretracheal fascia", "correct": false}, {"label": "D", "text": "Investing layer forms the floor of the posterior triangle", "correct": false}], "correct_answer": "A. Investing layer covers the parotid gland and submandibular gland", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681337012-QTDA024009IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Investing layer covers the parotid gland and submandibular gland The investing layer of the deep cervical fascia covers the parotid and submandibular glands.</p>\n<p><strong>Highyeild:</strong></p><p>The deep fascia in the neck is condensed to form the following layers: Investing layer- It forms the roof of the posterior and anterior triangle and splits to enclose Parotid gland Submandibular gland Pretracheal fascia- it spits to enclose the thyroid gland to form its false capsule. This capsule is thickened posteriorly and on either side forms the suspensory ligament which is known as the ligament of Berry, A Carotid sheath is formed anteriorly by pre tracheal fascia and posteriorly by the prevertebral fascia. It encloses: Common carotid artery Internal carotid artery Internal jugular vein Vagus nerve Prevertebral fascia- It forms the floor of the posterior triangle and the axillary sheath Inferiority, it blends with the buccopharyngeal fascia.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B - The pretracheal fascia covers the thyroid gland and forms its false capsule. The true capsule of the thyroid gland is formed by the gland itself. The parotid gland is covered by the superficial lamina of the investing layer of deep cervical fascia only. Option C. Axillary sheath is formed by the prevertebral fascia. Option D. The investing layer forms the roof of anterior and posterior triangles.</p>\n<p><strong>Extraedge:</strong></p><p>Buccopharyngeal fascia- It covers the outer surface of the pharyngeal constrictors and the buccinator. Posteriorly, It's separated from the prevertebral fascia by the retropharyngeal space. Pharyngobasilar fascia- it fills the gap between the superior constrictor and the base of the skull.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 54-year-old woman with papillary thyroid carcinoma develops a palpable lymph node in the suprasternal space of Burns. Which of the following structures is not closely related to these metastatic lymph nodes?", "options": [{"label": "A", "text": "Anterior jugular vein", "correct": false}, {"label": "B", "text": "Interclavicular ligament", "correct": false}, {"label": "C", "text": "Sternal head of sternocleidomastoid", "correct": false}, {"label": "D", "text": "External jugular vein", "correct": true}], "correct_answer": "D. External jugular vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>External jugular vein The external jugular vein is not present in the suprasternal space of Burns. It is present in the supraclavicular space, along with the supraclavicular nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Contents of the suprasternal space of Burns include: The jugular venous arch, formed by the anterior jugular veins Sternal head of right and left sternocleidomastoid Lymph nodes Interclavicular Ligament. Investing layer of the deep cervical fascia enclosing supraclavicular space. Investing layer of deep fascia encloses: (Can be remembered by the rule of twos) 2 muscles - sternocleidomastoid, trapezius 2 glands-parotid and submandibular gland 2 spaces - suprasternal space and supraclavicular space 2 ligaments - stylomandibular and sphenomandibular ligament.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Anterior jugular vein Option B. Interclavicular ligament Option C. Sternal head of sternocleidomastoid Options A, B and C all are content of the suprasternal space of Burn.</p>\n<p><strong>Extraedge:</strong></p><p>The supraclavicular space includes: Supraclavicular nerve External jugular vein</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 21-year-old student presents with a single episode of loss of consciousness. He was about to give a speech at his graduation ceremony when he suddenly turned pale and collapsed to the ground. Which of the following areas contain the nerve responsible for it?", "options": [{"label": "A", "text": "Area covered by investing sheath", "correct": false}, {"label": "B", "text": "Area covered by a carotid sheath", "correct": true}, {"label": "C", "text": "Prevertebral sheath", "correct": false}, {"label": "D", "text": "Pretracheal sheath", "correct": false}], "correct_answer": "B. Area covered by a carotid sheath", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Area covered by a carotid sheath The given scenario describes a vasovagal syncope triggered by a stressful event. The vagus nerve is a content of the carotid triangle covered by a carotid sheath.</p>\n<p><strong>Highyeild:</strong></p><p>Contents of the carotid triangle: Arteries: Common carotid artery, Internal and external carotid artery Branches of external carotid-superior thyroid, lingual, facial, ascending pharyngeal, and occipital artery Veins: Internal jugular vein Nerves: In the upper part of the sheath, there are IX, XI, and XII nerves also. Spinal part of accessory Sympathetic chain Ansa cervicalis Carotid sheath Note: Ansa Cervicalis is located anterior to the carotid sheath, while the sympathetic chain is located posterior to it. ie; they are NOT contents of the carotid sheath but are contents of the carotid triangle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Area covered by investing sheath, Option C. Prevertebral sheath and Option D. Pretracheal sheath all are incorrect because the given scenario describes a vasovagal syncope triggered by a stressful event. The vagus nerve is a content of the carotid triangle covered by a carotid sheath.</p>\n<p><strong>Extraedge:</strong></p><p>Carotid sheath extends from the base of the skull above to the arch of the aorta below . At the base of the skull, it is attached to the margins of the carotid canal and jugular fossa. At the arch of the aorta, it blends with its tunica adventitia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 40-year-old man after trauma sustained injury at work in a factory, presents with severe scalp lacerations, which were sutured. After 3 days the wound is inflamed, swollen, and painful. Between which tissue layers is the infection most likely located?", "options": [{"label": "A", "text": "The periosteum and bone", "correct": false}, {"label": "B", "text": "The aponeurosis and the loose areolar tissue", "correct": true}, {"label": "C", "text": "The dense connective tissue and the aponeurosis", "correct": false}, {"label": "D", "text": "The dense connective tissue and the skin", "correct": false}], "correct_answer": "B. The aponeurosis and the loose areolar tissue", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The aponeurosis and the loose areolar tissue The scalp is divided into five layers: skin, dense connective tissue, aponeurosis, loose connective tissue, and periosteum. A handy mnemonic is a SCALP (skin, connective tissue, aponeurosis, loose connective tissue, and periosteum). Typically, infections will be located in the loose connective tissue because of the ease with which infectious agents spread via the many veins located in this region.</p>\n<p><strong>Highyeild:</strong></p><p>The area of loose connective tissue is usually referred to as the “danger zone” of the scalp mainly because scalp infections here can be transmitted into the skull via emissary's veins, then via diploic veins of the bone to the cranial cavity.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. The periosteum and bone are tightly bound together; thus, it is not likely to find infections between these layers. Option C. The areas between the dense connective tissue and aponeurosis and between the connective tissue and the skin layers do not include connecting veins but mainly superficial veins of the head. Option D. The skin provides a very strong barrier against infections; the epidermis and dermis layers are rarely seen separated, and thus the likelihood of infection between these areas would be rare.</p>\n<p><strong>Extraedge:</strong></p><p>Loose areolar tissue: As the name indicates, this layer is made of loose areolar tissue. It serves as a natural plane of cleavage during craniotomy. This layer is traversed by emissary veins connecting veins in the second layer of the scalp with intracranial dural venous sinuses.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following muscles is the most important in jaw protrusion and depressing the mandible?", "options": [{"label": "A", "text": "Anterior portion of temporalis", "correct": false}, {"label": "B", "text": "Lateral pterygoid", "correct": true}, {"label": "C", "text": "Medial pterygoid", "correct": false}, {"label": "D", "text": "Masseter", "correct": false}], "correct_answer": "B. Lateral pterygoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral pterygoid The lateral pterygoid muscle is a muscle of mastication innervated by the lateral pterygoid nerve of the mandibular division of the trigeminal nerve. The lateral pterygoid acts to protrude the mandible and open the jaw.</p>\n<p><strong>Random:</strong></p><p>' Explanation for incorrect options:- Option A. The anterior portion of the temporalis is a muscle of mastication innervated by the deep temporal nerves of the mandibular division of the trigeminal nerve that elevates the mandible when contracted. Option C. The medial pterygoid muscle is a muscle of mastication innervated by the mandibular division of the trigeminal nerve. This muscle closes the jaw and works with the contralateral medial pterygoid in side-to-side (grinding) jaw movements. Option D. The masseter muscle is a muscle of mastication innervated by the mandibular division of the trigeminal nerve that specifically assists in chewing. The platysma is a thin muscle of facial expression that lies within the superficial fascia of the neck and lower face.</p>\n<p><strong>Extraedge:</strong></p><p>The action of Lateral pterygoid muscle Lateral pterygoids of two sides depress the mandible (opens the mouth) by pulling forward the condylar processes of the mandible and the articular discs of the temporomandibular joints. Lateral and medial pterygoid muscles of two sides acting together protrude from the mandible. Lateral and medial pterygoid muscles of the two sides contract alternately to produce side-to-side movements of the lower jaw as in chewing.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A neonate is born with micrognathia. CT scan and physical examination reveal hypoplasia of the mandible, underdevelopment of the bones of the face, downward-slanting palpebral fissures, defects of the lower eyelids, and deformed external ears. Abnormal development of which of the pharyngeal arches will most likely produce such symptoms?", "options": [{"label": "A", "text": "First Arch", "correct": true}, {"label": "B", "text": "Second Arch", "correct": false}, {"label": "C", "text": "Third Arch", "correct": false}, {"label": "D", "text": "Fourth Arch", "correct": false}], "correct_answer": "A. First Arch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>First Arch The first pharyngeal arch, which is often associated with the mandible, is responsible for the development of Meckel’s cartilage, malleus, incus, and mandible. Additionally, it is innervated by the trigeminal nerve, specifically the mandibular division that innervates the muscles of mastication. This patient presents with features characteristic of developmental defects in the first arch.</p>\n<p><strong>Highyeild:</strong></p><p>Hemifacial microsomia [oculoauriculovertebral spectrum or Goldenhar syndrome ] includes a number of craniofacial abnormalities that usually involve the maxillary, temporal, and zygomatic bones, which are small and flat. Ear [anotia, microtia], eye [tumours and dermoids in the eyeball], and vertebral [fused and hemivertebrae, spina bifida] defects are commonly observed in these patients.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. The second pharyngeal arch gives rise to the stapes, styloid process, lesser cornu, Reichert’s cartilage, and the upper half of the hyoid bone. It is innervated by the facial nerve. Option C. The third pharyngeal arch is responsible for the formation of the greater cornu and the lower half of the hyoid bone and is innervated by the glossopharyngeal nerve. Option D. The fourth and sixth pharyngeal arches give rise to the laryngeal cartilages, in addition to being innervated by the vagus nerve.</p>\n<p><strong>Extraedge:</strong></p><p>Treacher Collins syndrome [mandibulo- facial dysostosis] is a rare autosomal dominant disorder occurring in 1/50,000 live births with 60% of cases arising as new mutations. The syndrome is characterized by hypoplasia of the maxilla, mandible, and zygomatic arches, which may be absent. A cleft palate is common as are external ear defects accompanied by atresia of the auditory canals and abnormalities of the middle ear ossicles, such that bilateral conductive hearing loss is often The eyes are usually involved with down-slanting palpebral fissures and lower eyelid colobomas.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 24 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Horner's syndrome is sometimes seen in patients diagnosed with the lateral medullary syndrome. Which of the following is a characteristic feature of Horner syndrome?", "options": [{"label": "A", "text": "Atrophy of tongue musculature", "correct": false}, {"label": "B", "text": "Mydriasis", "correct": false}, {"label": "C", "text": "Paralysis of muscles of facial expression", "correct": false}, {"label": "D", "text": "Red blushing of the skin in the affected area", "correct": true}], "correct_answer": "D. Red blushing of the skin in the affected area", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Red blushing of the skin in the affected area The skin in the affected area is red and dry due to diminished sympathetic activity.</p>\n<p><strong>Highyeild:</strong></p><p>Horner syndrome is a rare condition classically presenting with partial ptosis (drooping or falling of the upper eyelid), miosis (constricted pupil), and facial anhidrosis (absence of sweating) due to a disruption in the sympathetic nerve supply.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Mydriasis The pupil on the affected side is constricted (miosis) due to the unopposed activity of the sphincter pupillae muscle. Option: A. Atrophy of tongue musculature Motor deficits such as atrophy of tongue musculature or paralysis of facial expression muscles are typically not part of Horner syndrome. Option: C. Paralysis of muscles of facial expression Motor deficits such as atrophy of tongue musculature or paralysis of facial expression muscles are typically not part of Horner syndrome.</p>\n<p><strong>Extraedge:</strong></p><p>Lateral medullary syndrome Anatomical location Presenting symptoms Spinothalamic tract Contralateral loss of pain and temperature sensation Spinal trigeminal nucleus Ipsilateral facial loss of pain and temperature Nucleus ambiguus Supplies vagus and glossopharyngeal nerves; dysphagia/dysphonia/ diminished gag reflex Inferior vestibular nucleus Vertigo/diplopia/nystagmus/ vomiting Sympathetic fibres Ipsilateral Horners syndrome Central trigeminal tract Palatal clonus Inferior cerebellar peduncle Ataxia</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The anatomic substrate for integrating cognitive, emotional, and expressive brain activities is provided by the Papez circuit. Which brain structures participate in the Papez circuit?", "options": [{"label": "A", "text": "Amygdala", "correct": false}, {"label": "B", "text": "Caudate nucleus", "correct": false}, {"label": "C", "text": "Mammillary nuclei", "correct": true}, {"label": "D", "text": "Suprachiasmatic nucleus", "correct": false}], "correct_answer": "C. Mammillary nuclei", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Mammillary nuclei The Papez circuit is formed by the hippocampus's efferent fibres, which project through the fornix to the mammillary nuclei in the hypothalamus. Axons from the mammillary nuclei project to the anterior thalamic nucleus, connected to the cingulate gyrus. The latter projects back to the hippocampus through the parahippocampal gyrus. Papez circuit integrates cortical, hypothalamic, and thalamic functions resulting in the integration of cognitive, emotional, and expressive brain functions. The ventrolateral thalamic nucleus is involved in motor pathways, being connected to the deep cerebellar nuclei and the motor cortex.</p>\n<p><strong>Highyeild:</strong></p><p>Papez Circuit The Papez circuit includes the following limbic structure Hippocampal formation. Mammillary body/nucleus. Anterior nucleus of the thalamus. Cingulate gyrus. Entorhinal cortex. Papez circuit</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Although the amygdala (choice A) is involved in emotional brain functions, it is not part of the Papez circuit. Option: B. The caudate nucleus (choice B) is a component of the basal ganglia and the extrapyramidal motor control system. Option: D. The suprachiasmatic nucleus (choice D) is located in the hypothalamus and mediates the circadian rhythm.</p>\n<p><strong>Extraedge:</strong></p><p>The cingulate gyrus is a ‘satisfaction centre’ of the brain and is associated with satisfaction after a meal or sexual intercourse.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An 8-year-old male is admitted to the hospital with a drooping right eyelid (ptosis). The initial diagnosis is Horner’s syndrome (Image). Which of the following additional signs on the right side would confirm the diagnosis?", "options": [{"label": "A", "text": "Constricted Pupil", "correct": true}, {"label": "B", "text": "Dry eye", "correct": false}, {"label": "C", "text": "Exophthalmos", "correct": false}, {"label": "D", "text": "Pale, blanched face", "correct": false}], "correct_answer": "A. Constricted Pupil", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392133907-QTDA061003IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Constricted Pupil Horner’s syndrome involves interrupting sympathetic supply to the face. This results in ptosis (drooping eyelid), miosis (constricted pupil), and anhidrosis (lack of sweating) of the face. The eye is lubricated by the lacrimal gland, which secretes in response to parasympathetic stimulation and is unaffected. Exophthalmos (protrusion of the globe) is frequently caused by hyperthyroidism and is not present in Horner’s syndrome. Loss of sympathetic innervation leads to unopposed vasodilatation of the vessels to the face, leading to flushing rather than paleness.</p>\n<p><strong>Highyeild:</strong></p><p>Horner syndrome is a rare condition classically presenting with partial ptosis (drooping or falling of the upper eyelid), miosis (constricted pupil), and facial anhidrosis (absence of sweating) due to a disruption in the sympathetic nerve supply.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Dry eye The eye is lubricated by the lacrimal gland, which secretes in response to parasympathetic stimulation and is unaffected. Option: C. Exophthalmos Exophthalmos (protrusion of the globe) is frequently caused by hyperthyroidism and is not present in Horner’s syndrome. Option: D. Pale, blanched face Loss of sympathetic innervation leads to unopposed vasodilatation of the vessels to the face, leading to flushing rather than paleness.</p>\n<p><strong>Extraedge:</strong></p><p>Branches of superior, middle and inferior cervical ganglia Superior cervical ganglion Middle cervical ganglion Inferior cervical ganglion Arterial branches (i) Along internal carotid artery as internal carotid nerve (ii) Along common carotid and external carotid arteries Along the inferior thyroid artery Along subclavian and vertebral arteries Grey rami communicantes Along cervical 1-4 nerves Along 5 and 6 cervical nerves Along 7 and 8 cervical nerves Along cranial nerves Along IX, X, XI, and XII cranial nerves - - Visceral branches Pharynx, thyroid, cardiac Cardiac Cardiac</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following descending tracts are anterior in position except", "options": [{"label": "A", "text": "Olivospinal", "correct": false}, {"label": "B", "text": "Rubrospinal", "correct": true}, {"label": "C", "text": "Vestibulospinal", "correct": false}, {"label": "D", "text": "Tectospinal", "correct": false}], "correct_answer": "B. Rubrospinal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Rubrospinal The rubrospinal tract originates from the red nucleus of the midbrain tegmentum and crosses the midline in ventral tegmental decussation located in the caudal midbrain. The tract forms a contralateral tract in the dorsolateral part of the lateral funiculus and lies in the ventrolateral part of the spinal cord. Transverse section of spinal cord</p>\n<p><strong>Highyeild:</strong></p><p>The descending tracts Name Function Crossed and uncrossed Beginning Termination Pyramidal tracts 1. Lateral corticospinal Main motor tract for skilful voluntary movements Crosses in medulla Motor area of the cortex (areas 4, 6) Anterior grey column cells (alpha motor neurons) 2. Anterior corticospinal Facilitates flexors Crosses in the corresponding spinal segment Motor area of the cortex (areas 4, 6) Anterior grey column cells (alpha motor neurons) Extrapyramidal tracts 1. Rubrospinal Efferent pathway for cere- bellum and corpus striatum Crossed The red nucleus of the midbrain Alpha and gamma motor neurons of anterior grey column cells 2. Medial reticulospinal The extrapyramidal tract Facilitates extensors Uncrossed Reticular formation of the grey matter of pons Alpha and gamma motor neurons of anterior grey column cells 3. Lateral reticulospinal The extrapyramidal tract Facilitates flexors Uncrossed and crossed Reticular formation of the grey matter of medulla oblongata Alpha and gamma motor neurons of anterior grey column cells 4. Olivospinal Extrapyramidal tract Uncrossed Inferior olivary nucleus Alpha and gamma motor neurons of anterior grey column cells 5. Lateral vestibulospinal Efferent pathway for equilibratory control Uncrossed Lateral vestibular nucleus Alpha and gamma motor neurons of anterior grey column cells 6. Tectospinal Efferent pathway for visual reflexes Crossed Superior colliculus Alpha and gamma motor neurons of anterior grey column cells 7. Descending auto-nomic fibres Control parasympathetic and sympathetic systems Cerebral cortex hypothalamus reticular formation Parasympathetic and sympathetic outflows</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Olivospinal Option: C. Vestibulospinal Option: D. Tectospinal The Olivospinal, Vestibulospinal and Tectospinal tracts are located anteriorly in the transverse section of the spinal cord.</p>\n<p><strong>Extraedge:</strong></p><p>The ascending tracts of the spinal cord Name Function Crossed and uncrossed Beginning Termination 1. Lateral spinothalamic (axons of 2nd-order neurons Pain and temperature from the opposite half of the body Cross to the opposite side in the same spinal segment Laminae I-IV of posterior grey column (substantia gelatinosa) Forms spinal lemniscus in medulla reaches the posterolateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 2. Anterior spinothalamic (axons of 2nd order neurons) Touch (crude) and pressure from the opposite half of the body Ascends to 2-3 spinal segments to cross to the opposite side Laminae I-IV of posterior grey column Joins medial lemniscus in the brainstem, reaches the posterolateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 3. Fasciculus gracilis (axons of 1st order sensory neurons) (lower limb) Conscious proprioception Discriminatory touch Vibratory sense Stereognosis Uncrossed Dorsal root ganglion cells relay and ends in areas 3, 1, 2 Relays in nucleus gracilis, 2nd order fibres form medial lemniscus, which reaches the posterolateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 4. Fasciculus cuneatus (axons of 1st order sensory neurons) (upper limb) Same as above Same as above Same as above Relays in nucleus cuneatus, rest is same as above 5. Posterior spino- cerebellar (axons of 2nd order neurons) Unconscious proprioception from individual lower limb muscles Uncrossed Laminae V, VI of posterior grey column Vermis of the cerebellum (via inferior cerebellar peduncle) 6. Anterior spinocere- Bellar (axons of 2nd order neurons) Unconscious proprio- ception from the lower limb as a whole Crosses twice, once in the spinal cord and recros- ses in the midbrain Laminae V, VI of posterior grey column Vermis of the cerebellum (via superior cerebellar peduncle) via recrossing 7. Spino-olivary (axons of 2nd-order neurons) Proprioceptive sense Uncrossed Laminae I-IV column Dorsal and medial accessory olivary nuclei 8. Spinotectal (axons of 2nd order neurons) The afferent limb of reflex movements of eyes and head Crossed Laminae I-IV column Tectum or superior colliculus of the midbrain</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 56-year-old man comes to the emergency department because of a high-speed motor vehicle accident that caused a laceration to his left spinal cord at the T8 vertebral level. After emergency surgery, he is in stable condition, and his temperature is 37.3°C (99.1°F), pulse is 80/min, respirations are 18/min, and blood pressure is 142/90 mm Hg. He is alert and oriented to person, place, and time while resting in his hospital bed. He says his pain is managed well, but he is concerned about his spinal cord injury. Which of the following neurologic deficits is most likely found on the physical examination of this patient?", "options": [{"label": "A", "text": "Loss of left side pain and temperature sensation below the injury", "correct": false}, {"label": "B", "text": "Loss of sensation in the left side below the injury for proprioception", "correct": true}, {"label": "C", "text": "Loss of right-side motor control", "correct": false}, {"label": "D", "text": "Loss in right side for fine touch and proprioception.", "correct": false}], "correct_answer": "B. Loss of sensation in the left side below the injury for proprioception", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Loss of sensation in the left side below the injury for proprioception The patient has Brown Sequard syndrome at the T8 level left side. He will experience: Ipsilateral loss of motor control, as the corticospinal tracts cross high up in the pyramids. Contralateral loss of pain and temperature, as the lateral spinothalamic tracts cross at the same spinal level or 2-3 segments above it. Ipsilateral loss of fine touch and proprioception as the dorsal column tracts don’t cross.</p>\n<p><strong>Highyeild:</strong></p><p>Comparison between lower motor neuron (LMN) and upper motor neuron (UMN) paralyses LMN paralysis UMN paralysis Muscle tone abolished Muscle tone increased Leads to flaccid paralysis Leads to spastic paralysis Muscles atrophy later No atrophy of muscles The reaction of degeneration seen The reaction of degeneration is not seen Tendon reflexes absent Tendon reflexes exaggerated Limited damage Extensive damage Ipsilateral Mostly contralateral Babinski sign negative Babinski sign positive All superficial and deep reflexes lost due to damage to motor pathways Superficial reflexes, like abdominal, cremasteric, and plantar, are lost due to damage to corticospinal tracts It may affect a single muscle group, as in poliomyelitis and Bell's palsy Affects many groups of muscles, as in hemiplegia. Damage to the corticospinal tract removes the inhibitory effect on the superficial reflexes, resulting in Babinski positive sign. There is a loss of control of lower motor neurons, which become hyperactive, leading to spastic paralysis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Pain and temperature will be lost on the right side, not the left. Option: C. Motor control will be lost on the left side. Option: D. Fine touch and proprioception will be lost on the left side.</p>\n<p><strong>Extraedge:</strong></p><p>Syringomyelia (central spinal cord syndrome): Cavities are formed around the central canal, usually in the lower cervical region. Its features are: Bilateral loss of pain and temperature occurs due to injury to the decussating fibres of lateral spinothalamic fibres. Bilateral loss of touch occurs due to injury to the anterior spinothalamic tract. As the decussation of lateral and anterior spino- thalamic tracts occurs at different levels, there is dissociated sensory loss. As this disease occurs in the lower cervical and upper thoracic regions, there is a problem in both the upper limbs and the front of the chest. Syringomyelia disrupts the crossing fibres of the anterolateral system. The medial lemniscal system is spared.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "What is the most common clinical cord syndrome in incomplete injuries?", "options": [{"label": "A", "text": "Central Cord Syndrome", "correct": true}, {"label": "B", "text": "Conus medullaris", "correct": false}, {"label": "C", "text": "Cauda equina", "correct": false}, {"label": "D", "text": "Brown Sequard syndrome", "correct": false}], "correct_answer": "A. Central Cord Syndrome", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Central Cord Syndrome Central cord syndrome is the most common incomplete cord injury and almost always occurs due to a traumatic injury.</p>\n<p><strong>Highyeild:</strong></p><p>Syndrome Mechanism Clinical Prognosis Anterior cord Flexion or vascular Complete loss of motor, pain, & temperature below the injury, but retains proprioception and vibratory sensation Poor Central cord Forced hyperextension Sensory and motor deficit Upper > Lower Extremities Average Brown- Séquard Brown- Séquard Ipsilateral loss of motor, vibratory sensation, and proprioception with contralateral loss of pain and temperature sensation Good</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B, C, and D. are not the most common clinical cord syndromes.</p>\n<p><strong>Extraedge:</strong></p><p>Syringomyelia In this condition, a fluid cavity (or cavities) develops near the centre of the spinal cord, usually in the cervical segments. This leads to the destruction of the cord involving the central canal and its surrounding area. This lesion involves the decussating spinothalamic fibres in the anterior white commissure so that there is a bilateral loss of pain and temperature sensations below the lesion. Other sensations are preserved in the uncrossed tracts of posterior columns. Thus, this condition results in what is called dissociated sensory loss.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 32-year-old female presented to the ED because of sudden lower back pain with positive symptoms of cauda equina syndrome, X-ray was done, and it was normal. What is the best investigation to confirm the diagnosis?", "options": [{"label": "A", "text": "Bone Scan", "correct": false}, {"label": "B", "text": "MRI", "correct": true}, {"label": "C", "text": "USG", "correct": false}, {"label": "D", "text": "DEXA", "correct": false}], "correct_answer": "B. MRI", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>MRI MRI is the best scan for viewing bone marrow, spinal cord and soft tissues.</p>\n<p><strong>Highyeild:</strong></p><p>Magnetic resonance imaging (MRI) is a medical imaging technique that uses a magnetic field and computer-generated radio waves to create detailed images of the organs and tissues in your body.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Bone scan is for viewing the osteoblastic activity in the bones, usually in cases of bone metastases, and stress fractures Option: C. USG is irrelevant for cauda equina Option: D . DEXA is used for assessing bone mineral density in cases of osteoporosis.</p>\n<p><strong>Extraedge:</strong></p><p>A computed tomography scan (usually abbreviated to CT scan , formerly computed axial tomography scan or CAT scan ) is a medical imaging technique used to obtain detailed internal images of the body. The personnel that perform CT scans are called radiographers or radiology technologists.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not true regarding anterior cord syndrome?", "options": [{"label": "A", "text": "Loss of motor below the level", "correct": false}, {"label": "B", "text": "Loss of proprioception/vibration", "correct": true}, {"label": "C", "text": "Loss of pain and temp", "correct": false}, {"label": "D", "text": "Both B & C", "correct": false}], "correct_answer": "B. Loss of proprioception/vibration", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Loss of proprioception/vibration Anterior cord syndrome involves the spinothalamic tracts, corticospinal tracts, and spinocerebellar tracts but not the dorsal columns.</p>\n<p><strong>Highyeild:</strong></p><p>Anterior cord syndrome is an incomplete cord syndrome that predominantly affects the anterior 2/3 of the spinal cord, characteristically resulting in motor paralysis below the lesion level and the loss of pain and temperature at and below the level of the lesion.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Corticospinal tracts are involved in anterior cord syndrome Option: C. Loss of pain and temperature will occur in anterior cord syndrome</p>\n<p><strong>Extraedge:</strong></p><p>Anterior spinal artery syndrome It occurs due to occlusion (thrombosis or compression of the anterior spinal artery). Each segmental artery divides into anterior and posterior branches, which enter the vertebral canal along the corresponding spinal nerve's anterior and posterior nerve roots; hence termed anterior and posterior radicular arteries, respectively. Many of these radicular arteries are small and end by supplying the spinal nerve roots. Since the anterior spinal artery supplies the anterior two-thirds of the cord, the occlusion of this artery will therefore result in motor symptoms due to the involvement of corticospinal tracts and anterior gray columns and bilateral loss of pain and temperature sensation due to ischaemia of spinothalamic tracts.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The conus medullaris:", "options": [{"label": "A", "text": "Exhibits both a cervical and lumbar enlargement", "correct": false}, {"label": "B", "text": "Has a modification of neural tissue extending from its termination to the coccygeal ligament", "correct": false}, {"label": "C", "text": "Gives origin to most of the cauda equina", "correct": true}, {"label": "D", "text": "Is found at its lowest extent at S2", "correct": false}], "correct_answer": "C. Gives origin to most of the cauda equina", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Gives origin to most of the cauda equina The conus medullaris and cauda equina give rise to spinal nerves L2-S5 and the coccygeal nerve. The anterior rami of these spinal nerves contribute to the lumbar and sacral plexuses, which provide motor and sensory innervation to the entire lower limb, pelvic and perineal regions.</p>\n<p><strong>Highyeild:</strong></p><p>Cauda equina syndrome Cauda equina syndrome is caused by a compression or irritation of lumbosacral spinal nerve roots, often due to lumbar disc herniation. The most common symptoms include low back pain that radiates into the sacral region and legs, and bilateral motor and sensory deficits, which present as asymmetric saddle anaesthesia (S2-S5 dermatomes) and asymmetric lower limb weakness. Additional clinical features may include loss of bladder control (urinary retention), faecal incontinence and erectile dysfunction, which are often late findings and less frequent.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Exhibits both a cervical and lumbar enlargement Located at L2, the conus medullaris is the proper tapered spinal cord termination. Most of the cauda equina originate from the conus medullaris and then travel to the vertebral foramina inferior. Although the spinal cord exhibits both a cervical and a lumbar enlargement, the conus medullaris refers to the termination of the spinal cord, not the entire spinal cord. Option: B. Has a modification of neural tissue extending from its termination to the coccygeal ligament. There is no modified neural tissue extending from the termination of the conus medullaris to the coccygeal ligament. Instead, the filum terminal internum, a thread-like extension of the pia mater, extends from the conus medullaris. Eventually, this terminal internum becomes enclosed in the filum terminale externum, a thread-like extension of the dura mater extending below the end of the dural sac (at the S2 level). The filum terminal externum attaches to the coccyx, forming the coccygeal ligament. Option: D. The conus medullaris is located at L2, at the term examination of the spinal cord. The dural sac, however, continues to the S2 level.</p>\n<p><strong>Extraedge:</strong></p><p>Conus medullaris syndrome Conus medullaris syndrome, although quite similar, is clinically distinct from cauda equina syndrome. This syndrome is much less common and is typically caused by tumours or vascular anomalies within the spinal canal. It is characterised by symmetric saddle anaesthesia and symmetric weakness in the lower extremities, with associated bladder dysfunction and early bowel incontinence.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The dural sac and the subarachnoid space end at which vertebral level?", "options": [{"label": "A", "text": "L 4", "correct": false}, {"label": "B", "text": "L 5", "correct": false}, {"label": "C", "text": "S 2", "correct": true}, {"label": "D", "text": "S 1", "correct": false}], "correct_answer": "C. S 2", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>S 2 Although the dural sac and subarachnoid space end at S2, the filum terminale externum (coccygeal ligament) continues the dura mater that extends below the end of the dural sac to attaches to the coccyx.</p>\n<p><strong>Highyeild:</strong></p><p>The spinal cord is roughly cylindrical. It begins superiorly at the foramen magnum in the skull, where It is continuous with the medulla oblongata of the brain, and it terminates inferiorly in the adult at the level of the lower border of the first lumbar vertebra. In the young child, it is relatively long and usually ends at the upper border of the third lumbar vertebra. Thus, it occupies the upper two-thirds of the vertebral canal of the vertebral column and is surrounded by the three meninges, the dura mater, the arachnoid mater, and the pia mater. Further protection is provided by the cerebrospinal fluid (CSF), which surrounds the spinal cord in the subarachnoid space.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options : A, B, D. L4, L5, and S1 are irrelevant for filum terminale.</p>\n<p><strong>Extraedge:</strong></p><p>Comparison of Structural Details in Different Regions of the Spinal Cord Gray Matter Region Shape White Matter Anterior Gray Column Posterior Gray Column Lateral Gray Column Cervical Oval Fasciculus cuneatus and fasciculus gracilis present Medial group of cells for neck muscles; a central group of cells for accessory nucleus (C1-C5) and phrenic nucleus (C3-C5); a lateral group of cells for upper limb muscles Substantia gelatinosa present, continuous with Sp.N. of cranial nerve V at level C2; nucleus proprius present; nucleus dorsalis (Clarke column) absent Absent Thoracic Round Fasciculus cuneatus (T1-T6) and fasciculus gracilis present Medial group of cells for trunk muscles Substantia gelatinosa, nucleus proprius, and visceral afferent nucleus are present. Present; gives rise to preganglionic sympathetic fibres Lumbar Round to oval Fasciculus cuneatus absent; fasciculus gracilis present Medial group of cells for lower limb muscles; a central group of cells for lumbosacral nerve Substantia gelatinosa, nucleus proprius, nucleus dorsalis (Clarke column) at L1-L4, and visceral afferent nucleus present Present (L1-L2 [3]); gives rise to preganglionic sympathetic fibres Sacral Round Small amount; fasciculus cuneatus absent; fasciculus gracilis present Medial group of cells for lower limb and perineal muscles Substantia gelatinosa and nucleus proprius present Absent; group of cells present at S2-S4 for parasympathetic outflow</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The diagram in the anatomy class shows different types of tracts in the spinal cord. Identify the false statement regarding the marked tract.", "options": [{"label": "A", "text": "Anterior corticospinal tract- carries crude touch and pressure.", "correct": true}, {"label": "B", "text": "Lateral corticospinal tract decussate at the level of pontomedullary junction.", "correct": false}, {"label": "C", "text": "Rubrospinal facilitates flexor and inhibits extensor.", "correct": false}, {"label": "D", "text": "Vestibulospinal tract helps to maintain posture unconsciously.", "correct": false}], "correct_answer": "A. Anterior corticospinal tract- carries crude touch and pressure.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392135058-QTDA061011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior corticospinal tract- carries crude touch and pressure. The anterior spinal tract is a motor tract, i.e. descending pathway. It will not carry sensations like crude touch and pressure.</p>\n<p><strong>Highyeild:</strong></p><p>The descending tracts Name Function Crossed and uncrossed Beginning Termination Pyramidal tracts 1. Lateral corticospinal Main motor tract for skilful voluntary movements Crosses in medulla Motor area of the cortex (areas 4, 6) Anterior grey column cells (alpha motor neurons) 2. Anterior corticospinal Facilitates flexors Crosses in the corresponding spinal segment Motor area of the cortex (areas 4, 6) Anterior grey column cells (alpha motor neurons) Extrapyramidal tracts 1. Rubrospinal Efferent pathway for cere- bellum and corpus striatum Crossed The red nucleus of the midbrain Alpha and gamma motor neurons of anterior grey column cells 2. Medial reticulospinal The extrapyramidal tract Facilitates extensors Uncrossed Reticular formation of the grey matter of pons Alpha and gamma motor neurons of anterior grey column cells 3. Lateral reticulospinal The extrapyramidal tract Facilitates flexors Uncrossed and crossed Reticular formation of the grey matter of medulla oblongata Alpha and gamma motor neurons of anterior grey column cells 4. Olivospinal Extrapyramidal tract Uncrossed Inferior olivary nucleus Alpha and gamma motor neurons of anterior grey column cells 5. Lateral vestibulospinal Efferent pathway for equilibratory control Uncrossed Lateral vestibular nucleus Alpha and gamma motor neurons of anterior grey column cells 6. Tectospinal Efferent pathway for visual reflexes Crossed Superior colliculus Alpha and gamma motor neurons of anterior grey column cells 7. Descending auto-nomic fibres Control parasympathetic and sympathetic systems Cerebral cortex hypothalamus reticular formation Parasympathetic and sympathetic outflows</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Lateral corticospinal tract decussates at the level of pontomedullary junction Is a correct statement Option: C. Rubrospinal facilitate flexor and inhibit extensor is a correct statement Option: D. Vestibulospinal tract helps to maintain posture unconsciously is also a correct statement.</p>\n<p><strong>Extraedge:</strong></p><p>The ascending tracts of the spinal cord Name Function Crossed and uncrossed Beginning Termination 1. Lateral spinothalamic (axons of 2nd-order neurons Pain and temperature from the opposite half of the body Crosses to the opposite side in the same spinal segment Laminae I-IV of posterior grey column (substantia gelatinosa) Forms spinal lemniscus in medulla reaches the posterolateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 2. Anterior spinothalamic (axons of 2nd order neurons) Touch (crude) and pressure from the opposite half of the body Ascends to 2-3 spinal segments to cross to the opposite side Laminae I-IV of posterior grey column Joins medial lemniscus in the brainstem, reaches the posterolateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 3. Fasciculus gracilis (axons of 1st order sensory neurons) (lower limb) Conscious proprioception Discriminatory touch Vibratory sense Stereognosis Uncrossed Dorsal root ganglion cells relay and ends in areas 3, 1, 2 Relays in nucleus gracilis, 2nd order fibres form medial lemniscus, which reaches the posterolateral ventral nucleus of thalamus for another relay and ends in areas 3, 1, 2 4. Fasciculus cuneatus (axons of 1st order sensory neurons) (upper limb) Same as above Same as above Same as above Relays in nucleus cuneatus, rest is same as above 5. Posterior spino- cerebellar (axons of 2nd order neurons) Unconscious proprioception from individual muscles of the lower limb Uncrossed Laminae V, VI of posterior grey column Vermis of the cerebellum (via inferior cerebellar peduncle) 6. Anterior spinocere- Bellar (axons of 2nd order neurons) Unconscious proprio- ception from the lower limb as a whole Crosses twice, once in the spinal cord and recros- ses in the midbrain Laminae V, VI of posterior grey column Vermis of the cerebellum (via superior cerebellar peduncle) via recrossing 7. Spino-olivary (axons of 2nd-order neurons) Proprioceptive sense Uncrossed Laminae I-IV column Dorsal and medial accessory olivary nuclei 8. Spinotectal (axons of 2nd order neurons) The afferent limb of reflex movements of the eyes and head Crossed Laminae I-IV column Tectum or superior colliculus of the midbrain</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were handed the gross specimen of the following structure during your final professional examination. You were asked about the decussation which occurs at this level. Your answer will be-", "options": [{"label": "A", "text": "Ventral tegmental decussation- rubrospinal, dorsal tegmental decussation- tectospinal", "correct": true}, {"label": "B", "text": "Ventral tegmental decussation- tectospinal, dorsal tegmental decussation- rubrospinal", "correct": false}, {"label": "C", "text": "Ventral tegmental decussation- vestibulospinal and dorsal tegmental decussation- rubrospinal", "correct": false}, {"label": "D", "text": "Ventral tegmental decussation- tectospinal, dorsal tegmental decussation-vestibulospinal.", "correct": false}], "correct_answer": "A. Ventral tegmental decussation- rubrospinal, dorsal tegmental decussation- tectospinal", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392135335-QTDA061012IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ventral tegmental decussation- rubrospinal, dorsal tegmental decussation- tectospinal In the given question, the image shows a cross-section at the midbrain level, where the rubrospinal tract originates from the red nucleus and undergoes ventral tegmentum decussation. The tectospinal tract originates at the level of the superior colliculus and undergoes dorsal tegmental decussation. Hence the correct answer to this question will be option A.</p>\n<p><strong>Highyeild:</strong></p><p>Structural Components and functions of the Midbrain Components Functions Grey matter ● Superior colliculi Reflex centres for visual reflexes ● Inferior colliculi Lower auditory centres, probably concemed with reflexes involving auditory stimuli ● Red nuclei Involuntary control of muscle tone and posture ● Substantia nigra Regulate the activity of basal nuclei ● Nuclei of oculomotor and trochlear nerves Give motor fibres to these nerves, which are concerned with the activities of both intrinsic and extrinsic muscles of the eyeball White matter ● Cerebral peduncles containing several ascending and descending tracts Provides passage to the fibres of motor and sensory tracts</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Ventral tegmental decussation- tectospinal, dorsal tegmental decussation- rubrospinal Option: C. Ventral tegmental decussation- vestibulospinal and dorsal tegmental decussation- rubrospinal Option: D. Ventral tegmental decussation- tectospinal, dorsal tegmental decussation-vestibulospinal. In the given question, the image shows a cross-section at the midbrain level, where the rubrospinal tract originates from the red nucleus and undergoes ventral tegmentum decussation. The tectospinal tract originates at the level of the superior colliculus and undergoes dorsal tegmental decussation. Therefore, options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Most of the blood supply of the midbrain is derived from basilar artery branches. Besides this, it also receives arterial supply from the following arteries. Posterior cerebral Superior cerebellar Posterior communicating Anterior choroidal</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were posted in the radiology department during your internship, where you see the following image. The JR posted asks you about the decussating tract, which will be affected in this patient.", "options": [{"label": "A", "text": "Spinothalamic Tract.", "correct": true}, {"label": "B", "text": "Lateral corticospinal tract.", "correct": false}, {"label": "C", "text": "Dorsal column", "correct": false}, {"label": "D", "text": "All of the above.", "correct": false}], "correct_answer": "A. Spinothalamic Tract.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392135617-QTDA061013IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spinothalamic Tract. In the given question, the radiological image shows the appearance of syringomyelia. In this case, the tract which decussates and gets affected is the spinothalamic tract. Hence, the answer is option A.</p>\n<p><strong>Highyeild:</strong></p><p>Syringomyelia In this condition, a fluid cavity (or cavities) develops near the centre of the spinal cord, usually in the cervical segments. This leads to the destruction of the cord involving the central canal and its surrounding area. This lesion involves the decussating spinothalamic fibres in the anterior white commissure so that there is a bilateral loss of pain and temperature sensations below the lesion. Still, other sensations are preserved in the uncrossed tracts of posterior columns. Thus, this condition results in what is called dissociated sensory loss .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Lateral corticospinal tract Option: C. Dorsal column Option: D. All of the above In the given question, the radiological image shows the appearance of syringomyelia. In this case, the tract which decussates and gets affected is the spinothalamic tract. Therefore Options B, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Amyotrophic lateral sclerosis : It is a degenerative disease that is caused due damage to the cells in the ventral horn. The clinical features involve weakness, atrophy of muscles of hands and arms, and later extending to the lower limb.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were posted in the medicine ward during your internship when you saw a case of Brown Sequard syndrome. Which of the following symptoms associated with this condition is true?", "options": [{"label": "A", "text": "There is C/L loss of proprioception and vibration.", "correct": false}, {"label": "B", "text": "I/L spastic paralysis is seen.", "correct": false}, {"label": "C", "text": "C/L loss of pain and temperature below the level of the lesion.", "correct": false}, {"label": "D", "text": "Both B and C.", "correct": true}], "correct_answer": "D. Both B and C.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Both B and C. In the given case, the patient with brown Sequard syndrome will have the following feature- Option A. There is I/L loss of proprioception and vibration due to the dorsal column and not C/L. Option B. I/L spastic paralysis is seen due to the corticospinal tract. Option C. C/L loss of pain and temperature below the lesion level due to spinothalamic tract. Hence, only statement A given in the question is wrong. Therefore, option D is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Anterior spinal artery syndrome It occurs due to occlusion (thrombosis or compression of the anterior spinal artery). Each segmental artery divides into anterior and posterior branches, which enter the vertebral canal along the corresponding spinal nerve's anterior and posterior nerve roots; hence termed anterior and posterior radicular arteries, respectively. Many of these radicular arteries are small and end by supplying the spinal nerve roots. Since the anterior spinal artery supplies the anterior two-thirds of the cord, the occlusion of this artery will therefore result in motor symptoms due to involvement of corticospinal tracts and anterior gray columns and bilateral loss of pain and temperature sensation due to ischaemia of spinothalamic tracts.</p>\n<p><strong>Extraedge:</strong></p><p>Posterior rhizotomy or cordotomy The intractable pain can be treated in selected cases by cutting the appropriate posterior nerve roots (posterior rhizotomy) or dividing the spinothalamic tract on the side opposite to the pain (cordotomy). A knife is passed 3 mm deep into the cord, anterior to the denticulate ligament, and then swept forward. It severs the lateral spinothalamic tract but preserves the pyramidal tract immediately behind it.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 24 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "In a vehicular accident, the musculocutaneous nerve was completely severed, but still, the person was able to weakly flex the elbow joint. All of the following muscles are responsible for the flexion of the elbow joint, except:", "options": [{"label": "A", "text": "Brachioradialis", "correct": false}, {"label": "B", "text": "Flexor carpi radialis", "correct": false}, {"label": "C", "text": "Ulnar head of pronator teres", "correct": true}, {"label": "D", "text": "Flexor carpi ulnaris", "correct": false}], "correct_answer": "C. Ulnar head of pronator teres", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ulnar head of pronator teres Ulnar head of pronator teres Only the ulnar head of the pronator teres here not having an origin from the medial epicondyle, It is chiefly involved in pronation.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Brachioradialis The brachioradialis is a muscle of the forearm that flexes the forearm at the elbow. It is also capable of both pronation and supination, depending on the position of the forearm. It is attached to the distal styloid process of the radius by way of the brachioradialis tendon, and to the lateral supracondylar ridge of the humerus. Option: B. Flexor carpi radialis Option: D. Flexor carpi ulnaris Flexor carpi ulnaris and radialis both have a common origin from the medial epicondyle So, muscles originating from the medial epicondyle are weak flexors</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Tennis elbow ( lateral epicondylitis ) is caused by a chronic inflammation or irritation of the origin (tendon) of the extensor muscles of the forearm from the lateral epicondyle of the humerus as a result of repetitive strain. It is a painful condition and common in tennis players and violinists. Golfer's elbow (medial epicondylitis) is a painful condition caused by a small tear or an inflammation or irritation in the origin of the flexor muscles of the forearm from the medial epicondyle. Avoidance of repetitive bending (flexing) of the forearm is advised in order to not compress the ulnar nerve. Nursemaid's elbow or pulled elbow is a radial head subluxation and occurs in toddlers when the child is lifted by the wrist. It is caused by a partial tear (or loose) of the annular ligament and thus the radial head to slip out of position .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In the following joint, which of the following structures is not intracapsular? Olecranon fossa Radial fossa Olecranon process Lateral epicondyle Radial head Select the correct answer from below code:", "options": [{"label": "A", "text": "A, C, D", "correct": false}, {"label": "B", "text": "C, D", "correct": true}, {"label": "C", "text": "A, D, E", "correct": false}, {"label": "D", "text": "B, C, E", "correct": false}], "correct_answer": "B. C, D", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683118966-QTDA099002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C, D In the given question, the joint shown is the elbow joint which is a type of hinge joint. The capsule of the elbow joint passes anteriorly from above the radial and coronoid fossa to the radial head and coronoid process below. Posteriorly, the olecranon fossa and radial head are included. The Olecranon process, lateral and medial epicondyle are extracapsular structures. Hence the structures which are not intracapsular in the above option are the olecranon process and lateral epicondyle.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Tennis elbow ( lateral epicondylitis ) is caused by a chronic inflammation or irritation of the origin (tendon) of the extensor muscles of the forearm from the lateral epicondyle of the humerus as a result of repetitive strain. It is a painful condition and common in tennis players and violinists. Golfer's elbow (medial epicondylitis) is a painful condition caused by a small tear or an inflammation or irritation in the origin of the flexor muscles of the forearm from the medial epicondyle. Avoidance of repetitive bending (flexing) of the forearm is advised in order to not compress the ulnar nerve. Nursemaid's elbow or pulled elbow is a radial head subluxation and occurs in toddlers when the child is lifted by the wrist. It is caused by a partial tear (or loose) of the annular ligament and thus the radial head to slip out of position .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "For the ligamentous support of the elbow joint, two important ligaments are being discussed in the theory class during 1st year Session. The image is shown below with A and B labels. Which of the following statements is correct regarding the Elbow joint?", "options": [{"label": "A", "text": "A represents the ulnar collateral ligament.", "correct": false}, {"label": "B", "text": "B represents the radial collateral ligament.", "correct": false}, {"label": "C", "text": "Ulnar nerve lies above the ligament A.", "correct": false}, {"label": "D", "text": "All of the above.", "correct": true}], "correct_answer": "D. All of the above.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683119026-QTDA099003IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above. In the given question, image A represents the ulnar c ollateral ligament which consists of 3 bands- anterior, posterior, and inferior band. It lies beneath the triceps, Flexor carpi ulnaris, ulnar nerve, and attachment of flexor digitorum superficialis. Image B represents the radial collateral ligament which extends from the lateral epicondyle to the annular ligament on the radius. HENCE, all the statements are correct. So the answer is option D.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Tennis elbow ( lateral epicondylitis ) is caused by a chronic inflammation or irritation of the origin (tendon) of the extensor muscles of the forearm from the lateral epicondyle of the humerus as a result of repetitive strain. It is a painful condition and common in tennis players and violinists. Golfer's elbow (medial epicondylitis) is a painful condition caused by a small tear or an inflammation or irritation in the origin of the flexor muscles of the forearm from the medial epicondyle. Avoidance of repetitive bending (flexing) of the forearm is advised in order to not compress the ulnar nerve. Nursemaid's elbow or pulled elbow is a radial head subluxation and occurs in toddlers when the child is lifted by the wrist. It is caused by a partial tear (or loose) of the annular ligament and thus the radial head to slip out of position .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 22-year male patient came with the complaint of pain around the Elbow joint to the OPD. You as an intern were posted there when the consultant asks you about the nerve supply of the elbow joint. Which of the following nerve will not be the answer?", "options": [{"label": "A", "text": "Musculocutaneous Nerve", "correct": false}, {"label": "B", "text": "Axillary nerve", "correct": true}, {"label": "C", "text": "Ulnar nerve", "correct": false}, {"label": "D", "text": "Radial nerve.", "correct": false}], "correct_answer": "B. Axillary nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Axillary nerve The elbow joint is innervated by filaments arising from all the main nerves of the upper limb, except for the axillary nerve . Hence, the answer will be option B.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Musculocutaneous Nerve The ulnar anterior part of the elbow is supplied by the median and musculocutaneous nerves. Option: C. Ulnar nerve The ulnar posterior part of the elbow joint is supplied by the ulnar nerve and the medial cutaneous nerve of the forearm Option D. Radial nerve . The radial nerve is the sole supplier of the radial posterior part of the elbow, and the radial anterior part of the elbow is innervated by both radial and musculocutaneous nerves. Hence, the answer will be option B.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Tennis elbow ( lateral epicondylitis ) is caused by a chronic inflammation or irritation of the origin (tendon) of the extensor muscles of the forearm from the lateral epicondyle of the humerus as a result of repetitive strain. It is a painful condition and common in tennis players and violinists. Golfer's elbow (medial epicondylitis) is a painful condition caused by a small tear or an inflammation or irritation in the origin of the flexor muscles of the forearm from the medial epicondyle. Avoidance of repetitive bending (flexing) of the forearm is advised in order to not compress the ulnar nerve. Nursemaid's elbow or pulled elbow is a radial head subluxation and occurs in toddlers when the child is lifted by the wrist. It is caused by a partial tear (or loose) of the annular ligament and thus the radial head to slip out of position .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 28-year-old male patient came with a complaint of weakness in their hands. He is not able to play piano like before. He gave a history of RTA due to which there was pain and injury around the elbow. The X-ray taken at that time is given below. Which of the following nerves is affected in the given condition?", "options": [{"label": "A", "text": "Axillary Nerve", "correct": false}, {"label": "B", "text": "Radial nerve", "correct": false}, {"label": "C", "text": "Ulnar nerve", "correct": true}, {"label": "D", "text": "Musculocutaneous nerve", "correct": false}], "correct_answer": "C. Ulnar nerve", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683119054-QTDA099005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ulnar nerve In the given question, a patient with a history of injury around the elbow and an X-ray showing, Medial epicondylar fracture of the humerus The ulnar nerve is the most vulnerable neurovascular structure in this type of injury. Inspection will reveal swelling to the medial aspect of the elbow. If there is more generalized swelling, this suggests elbow dislocation. Bruising to the medial aspect may be present, especially when the injury mechanism involves direct trauma. Valgus instability of the joint is common and careful examination and documentation of neurovascular status is imperative.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Axillary Nerve The axillary nerve is commonly involved in the fracture of the Surgical neck of the humerus. Option: B. Radial nerve One of the most common reasons for peripheral nerve palsy is an injury of the radial nerve associated with a fracture of the humeral shaft Option: D. Musculocutaneous nerve In displaced humeral fractures, Musculocutaneous nerve injury may be due to direct compression of the proximal aspect of the humeral shaft.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Tennis elbow ( lateral epicondylitis ) is caused by a chronic inflammation or irritation of the origin (tendon) of the extensor muscles of the forearm from the lateral epicondyle of the humerus as a result of repetitive strain. It is a painful condition and common in tennis players and violinists. Golfer's elbow (medial epicondylitis) is a painful condition caused by a small tear or an inflammation or irritation in the origin of the flexor muscles of the forearm from the medial epicondyle. Avoidance of repetitive bending (flexing) of the forearm is advised in order to not compress the ulnar nerve. Nursemaid's elbow or pulled elbow is a radial head subluxation and occurs in toddlers when the child is lifted by the wrist. It is caused by a partial tear (or loose) of the annular ligament and thus the radial head to slip out of position .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During your final professional examination, while giving an ortho practical exam, the professor asks you about the muscles responsible for the movement at the level of the hu-mero-ulnar joint. All of the following muscles will do the flexion at the elbow joint except:", "options": [{"label": "A", "text": "Biceps Brachii", "correct": false}, {"label": "B", "text": "Brachialis", "correct": false}, {"label": "C", "text": "Brachioradialis", "correct": false}, {"label": "D", "text": "Anconeus", "correct": true}], "correct_answer": "D. Anconeus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anconeus For movement around the elbow joint, Extension is done by the following muscles: Triceps and anconeus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Biceps Brachii Option: B. Brachialis Option: C . Brachioradialis For movement around the elbow joint, flexion around the elbow joint occurs with the help of the following muscle: Brachialis, brachioradialis, and biceps brachii.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Tennis elbow ( lateral epicondylitis ) is caused by a chronic inflammation or irritation of the origin (tendon) of the extensor muscles of the forearm from the lateral epicondyle of the humerus as a result of repetitive strain. It is a painful condition and common in tennis players and violinists. Golfer's elbow (medial epicondylitis) is a painful condition caused by a small tear or an inflammation or irritation in the origin of the flexor muscles of the forearm from the medial epicondyle. Avoidance of repetitive bending (flexing) of the forearm is advised in order to not compress the ulnar nerve. Nursemaid's elbow or pulled elbow is a radial head subluxation and occurs in toddlers when the child is lifted by the wrist. It is caused by a partial tear (or loose) of the annular ligament and thus the radial head to slip out of position .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The iliotibial band has an insertion of all of the following muscles EXCEPT:", "options": [{"label": "A", "text": "Tensor Fasciae Latae", "correct": false}, {"label": "B", "text": "Gluteus maximus", "correct": false}, {"label": "C", "text": "Gluteus minimus", "correct": true}, {"label": "D", "text": "Vastus lateralis", "correct": false}], "correct_answer": "C. Gluteus minimus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Gluteus minimus Gluteus minimus lies deep to gluteus medius. Both gluteus medius and gluteus minimus are supplied by superior gluteal nerves. The fan-shaped muscle arises from the outer surface of the ilium between the anterior and inferior gluteal lines and, behind, from the margin of the greater sciatic notch. The fibers converge below to the deep surface of an aponeurosis that ends in a tendon attached to an anterolateral ridge on the greater trochanter and contributes an expansion to the capsule of the hip joint.</p>\n<p><strong>Highyeild:</strong></p><p>Explanation for incorrect options:- Option A : Tensor fasciae Latae Option B : Gluteus maximus Option D : Few fibers of vastus lateralis</p>\n<p><strong>Random:</strong></p><p>The iliotibial band is the thickened band of fascia lata. It receives insertion of the following muscles: The iliotibial tract or iliotibial band (also known as Maissiat's band) is a longitudinal fibrous reinforcement of the fascia lata. The action of muscles associated with the ITB (tensor fasciae latae and some fibers of gluteus maximus) flex, extend, abduct, and laterally and medially rotate the hip. The ITB contributes to lateral knee stabilization. At its distal aspect, the iliotibial tract lies superficially to the vastus lateralis head of the quadriceps femoris, where some of the vastus lateralis fibers may blend with the tract . Its insertion at Gerdy's tubercle is anterior to that of the bicep femoris insertion into the head of the fibula.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statements is False with regards to Fascia lata?", "options": [{"label": "A", "text": "Attached inferiorly to the Tibial condyles", "correct": false}, {"label": "B", "text": "Receives insertions of Gluteus maximus", "correct": false}, {"label": "C", "text": "Causes flexion at the knee joint", "correct": true}, {"label": "D", "text": "Superiorly attached to the iliac crest", "correct": false}], "correct_answer": "C. Causes flexion at the knee joint", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Causes flexion at the knee joint Fascia lata is the deep fascia of the thigh . Laterally splits to enclose the theilio-tibial tract. The action of muscles associated with the ITB (tensor fasciae latae and some fibers of gluteus maximus) flex, extend, abduct, and laterally and medially rotate the hip. The ITB contributes to lateral knee stabilization. Therefore option C is an incorrect statement about the Ilio-tibial tract.</p>\n<p><strong>Highyeild:</strong></p><p>ITB causes flexion at the hip & extension at the knee joint.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options : Option A. Inferiorly ITB is attached to the lateral condyle of the tibia . Option B. ITB receives the insertions of Tensor fascia lata & gluteus maximus. It also receives a few fibers of Vastus lateralis . Option D. Superiorly the ITB is attached to the iliac crest & capsule of the hip joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Gluteus maximus is inserted on:", "options": [{"label": "A", "text": "Lesser Trochanter", "correct": false}, {"label": "B", "text": "Gluteal tuberosity", "correct": false}, {"label": "C", "text": "Iliotibial tract", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. Iliotibial tract", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Iliotibial tract The greater part of the gluteus maximus muscle is inserted into the iliotibial tract (3/4th part). Gluteus maximus and tensor fascia lata are inserted into the iliotibial tract.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following is/ are modifications of fascia latae? A. Iliotibial tract B. Saphenous opening C. Intermuscular septa D. None of the above Select the correct answer from the given below code::", "options": [{"label": "A", "text": "A, B, and C", "correct": true}, {"label": "B", "text": "B, C, and D", "correct": false}, {"label": "C", "text": "D, C, and A", "correct": false}, {"label": "D", "text": "C, B, and A", "correct": false}], "correct_answer": "A. A, B, and C", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A, B, and C Iliotibial Tract: The fascia lata is thickened laterally where it forms a 5 cm wide band called the iliotibial tract. Gluteus maximus and tensor fascia lata insert into the iliotibial tract . Superiorly the tract splits into two layers. The superficial lamina is attached to the tubercle of the iliac crest and the deep lamina to the capsule of the hip joint. Inferiorly, the tract is attached to a smooth area on the anterior surface of the lateral condyle of the Intermuscular septa: The deep surface of the fascia lata yields two intermuscular septa, which are attached to the whole of the linea aspera of the posterior femur and to its proximal and distal prolongations. The lateral septum, thicker and stronger than the medial one, extends from the attachment of the gluteus maximus to the lateral femoral condyle Saphenous opening: The saphenous opening is an aperture in the deep fascia, inferolateral to the medial end of the inguinal ligament, which allows passage for the long saphenous vein and other smaller vessels</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All the following statements are true regarding fascia lata except?", "options": [{"label": "A", "text": "Attached inferiorly to the tibial condyles and head of the fibula", "correct": false}, {"label": "B", "text": "Reinforced anteriorly by expansions from the quadriceps tendon", "correct": false}, {"label": "C", "text": "Attached to Scarpa’s fascia above the inguinal ligament", "correct": true}, {"label": "D", "text": "Continuous below the popliteal fossa into the deep fascia of the calf", "correct": false}], "correct_answer": "C. Attached to Scarpa’s fascia above the inguinal ligament", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Attached to Scarpa’s fascia above the inguinal ligament Scarpa's fascia lies below the Camper's fascia and above the external oblique muscle. It is connected laterally to the aponeurosis of the external oblique muscle. Medially it fades into the linea alba and pubic symphysis.</p>\n<p><strong>Highyeild:</strong></p><p>In the upper thigh just below the inguinal ligament, Scarpa’s fascia blends in with the fascia lata</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options: Option A. Attached inferiorly to the tibial condyles and head of the fibula Fascia lata: the fascia lata, the wide, deep fascia of the thigh, is thicker in the proximal and lateral parts of the thigh where tensor fasciae latae and an expansion from the gluteus maximus are attached to it. The fascia lata ends at the knee joint where it then becomes the deep fascia of the leg (the crural fascia). Attachments are made at bony prominences around the knee including the femoral and tibial condyles, patella, head of the fibula, and the tibial tuberosity Option B. Reinforced anteriorly by expansions from the quadriceps tendon Fascia lata is thin posteriorly and over the adductor muscles, but thicker around the knee, where it is strengthened by expansions from the tendon of biceps femoris laterally, sartorius medially, and quadriceps femoris anteriorly. The fascia lata is attached superiorly and posteriorly to the back of the sacrum and coccyx, laterally to the outer margin of the iliac crest, anteriorly to the inguinal ligament and superior ramus of the pubis, and medially to the inferior ramus of the pubis, the ramus and tuberosity of the ischium, and the lower border of the sacrotuberous ligament. Option D. Continuous below the popliteal fossa into the deep fascia of the calf The fascia lata ends at the knee joint where it then becomes the deep fascia of the leg (the crural fascia).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of these pairs of structures are inserted into the upper part of the iliotibial tract?", "options": [{"label": "A", "text": "Gluteus maximus and tensor fasciae latae", "correct": true}, {"label": "B", "text": "Gluteus maximus and pectineus", "correct": false}, {"label": "C", "text": "Pectineus and tensor fasciae latae", "correct": false}, {"label": "D", "text": "Adductor longus and pectineus", "correct": false}], "correct_answer": "A. Gluteus maximus and tensor fasciae latae", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Gluteus maximus and tensor fasciae latae Iliotibial Tract: The fascia lata is thickened laterally where it forms a 5 cm wide band called the iliotibial tract. Gluteus maximus and tensor fascia lata insert into the iliotibial tract . Superiorly the tract splits into two layers. The superficial lamina is attached to the tubercle of the iliac crest and the deep lamina to the capsule of the hip joint. Inferiorly, the tract is attached to a smooth area on the anterior surface of the lateral condyle of the tibia.</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options: Options B, and C: t he pectineus is inserted on the line extending from the lesser trochanter to the Linea aspera. Option D. The adductor longus is inserted along the medial lip of the Linea aspera between the vastus medialis and the adductors brevis and magnus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The stability of the weight-bearing extended knee is maintained by:", "options": [{"label": "A", "text": "Anterior Cruciate Ligament", "correct": false}, {"label": "B", "text": "Posterior cruciate ligament", "correct": false}, {"label": "C", "text": "Popliteus muscle", "correct": false}, {"label": "D", "text": "Iliotibial tract", "correct": true}], "correct_answer": "D. Iliotibial tract", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Iliotibial tract The iliotibial tract stabilizes the knee both in extension and in partial flexion and is therefore used constantly during walking and running. In leaning forwards with slightly flexed knees , the tract is the main support of the knee against gravity.</p>\n<p><strong>Highyeild:</strong></p><p>Both tensor fascia lata and gluteus maximus are inserted into the iliotibial tract .</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options: Option A. The anterior cruciate ligament resists the combined motions of anterior tibial translation and internal tibial rotation. Option B. The PCL functions as one of the main stabilizers of the knee joint and serves primarily to resist excessive posterior translation of the tibia relative to the femur. Option C. Popliteus is often referred to as the \"Key\" to unlocking the knee since it begins knee flexion by laterally rotating the femur on the tibia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Identify the arrow marked structure?", "options": [{"label": "A", "text": "Cytotrophoblast", "correct": true}, {"label": "B", "text": "Syncytiotrophoblast", "correct": false}, {"label": "C", "text": "Secondary villi", "correct": false}, {"label": "D", "text": "Inner cell mass", "correct": false}], "correct_answer": "A. Cytotrophoblast", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/questionImage-1690539216399-QTDA012001.jpg"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cytotrophoblast The arrow marked structure in the given image is cytotrophoblast.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. syncytiotrophoblast, Option: C. secondary villi and Option: D. inner cell mass are incorrect options.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Tertiary villi develops from which of the following structures? Cytotrophoblast Extra embryonic mesoderm Blood vessels Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,2", "correct": false}, {"label": "B", "text": "1,3", "correct": false}, {"label": "C", "text": "2,3", "correct": false}, {"label": "D", "text": "1,2,3", "correct": true}], "correct_answer": "D. 1,2,3", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,2,3 Tertiary villi is a complex containing a) cytotrophoblast,with b) extra embryonic mesoderm and invading c) blood vessels. Primary villi develops from a) cytotrophoblast. Secondary villi develops from a) cytotrophoblast with invading b) extra embryonic mesoderm</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "First structure developed to determine craniocaudal axis of embryo?", "options": [{"label": "A", "text": "Prechordal Plate", "correct": true}, {"label": "B", "text": "Notochord", "correct": false}, {"label": "C", "text": "Both a & b", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Prechordal Plate", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Prechordal Plate Prechordal plate is the first structure developed to determine craniocaudal axis of embryo whereas b) Notochord is the First structure developed to determine right and left axis in embryo. Hence c) Both a & b and d) None of the above are incorrect.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the correct sequence of development from primitive streak:", "options": [{"label": "A", "text": "Ectoderm - Mesoderm- Endoderm", "correct": false}, {"label": "B", "text": "Endoderm - Mesoderm- Ectoderm", "correct": true}, {"label": "C", "text": "Ectoderm - Endoderm - Mesoderm", "correct": false}, {"label": "D", "text": "Mesoderm- Ectoderm- Endoderm", "correct": false}], "correct_answer": "B. Endoderm - Mesoderm- Ectoderm", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Endoderm - Mesoderm- Ectoderm Primitive streak gives rise to endoderm followed by mesoderm followed by ectoderm in sequential order.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Ectoderm – Mesoderm- Endoderm, Option: C. Ectoderm – Endoderm – Mesoderm and Option: D. Mesoderm- Ectoderm- Endoderm are all incorrect.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about trophoblast? Consists of cytotrophoblast and syncytiotrophoblast Forms chorion Formed from outer cell mass Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,2", "correct": false}, {"label": "B", "text": "2,3", "correct": false}, {"label": "C", "text": "1,3", "correct": false}, {"label": "D", "text": "1,2,3", "correct": true}], "correct_answer": "D. 1,2,3", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,2,3 Trophoblast is c) Formed from outer cell mass It a) Consists of cytotrophoblast and syncytiotrophoblast and b) Forms chorion along with somatopleuric extra embryonic mesoderm</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A male new-born has a hemangioma on the left temporal region of his face and scalp. The cells forming the hemangioma are derived from which of the following cell layers?", "options": [{"label": "A", "text": "Ectoderm Only", "correct": false}, {"label": "B", "text": "Mesoderm only", "correct": true}, {"label": "C", "text": "Endoderm only", "correct": false}, {"label": "D", "text": "Ectoderm and mesoderm", "correct": false}], "correct_answer": "B. Mesoderm only", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Mesoderm only Hemangioma- Tumor in the blood vessels – blood vessels from mesoderm only. A hemangioma is a usually benign vascular tumor derived from blood vessel cell types, and blood vessels are mesoderm derivatives only.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 22-year-old male came with complaints of pain around the right anatomical snuff box after he fell on an outstretched hand. Which of the following options correctly represents the boundary of the anatomical snuff box?", "options": [{"label": "A", "text": "Laterally- abductor pollicis longus and extensor pollicis brevis, Medially- extensor pollicis longus", "correct": true}, {"label": "B", "text": "Laterally- extensor pollicis longus, Medially- abductor pollicis longus and extensor pollicis brevis", "correct": false}, {"label": "C", "text": "Laterally- abductor pollicis longus and extensor pollicis longus, Medially- extensor pollicis brevis", "correct": false}, {"label": "D", "text": "Laterally- extensor pollicis longus and extensor pollicis brevis, Medially- abductor pollicis longus", "correct": false}], "correct_answer": "A. Laterally- abductor pollicis longus and extensor pollicis brevis, Medially- extensor pollicis longus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Laterally- abductor pollicis longus and extensor pollicis brevis, Medially- extensor pollicis longus Laterally- abductor pollicis longus and extensor pollicis brevis, Medially- extensor pollicis longus Boundaries of Anatomical Snuffbox The medial border (ulnar side) of the snuffbox is the tendon of the extensor pollicis longus. The lateral border (radial side) is a pair of parallel and intimate tendons, of the extensor pollicis brevis and the abductor pollicis longus. The proximal border is formed by the styloid process of the radius The distal border is formed by the approximate apex of the schematic snuffbox isosceles triangle. The floor of the snuffbox varies depending on the position of the wrist, but both the trapezium and primarily the scaphoid can be palpated. The pain in the anatomical snuff box points towards a scaphoid fracture after a fall on an outstretched hand.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options B, C, and D are all incorrect statements regarding the boundaries of the Anatomical Snuffbox.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A male patient presented with an injury to the hand while falling off the bike on an outstretched hand. He has tenderness in one of the carpal bones which forms the floor of the anatomical snuff box along with two tendons. Through which of the following compartments of the extensor retinaculum do these two tendons pass?", "options": [{"label": "A", "text": "1", "correct": false}, {"label": "B", "text": "2", "correct": true}, {"label": "C", "text": "3", "correct": false}, {"label": "D", "text": "5", "correct": false}], "correct_answer": "B. 2", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2 In the given question, the tendons which form the floor of the anatomical snuff box are tendons of ECRL and ECRB. These two tendons pass from the 2nd compartment of the extensor retinaculum which is present towards the lateral side. Hence, the correct answer to this question will be option B. Extensor Compartments</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A, C, and D. are incorrect. Another compartment of the extensor retinaculum contains: Abductor pollicis longus and extensor pollicis brevis ECRL and ECRB( extensor carpi radialis longus and brevis) EPL (extensor pollicis longus) Extensor digitorum, extensor indicis Anterior interosseous artery, and posterior interosseous nerve. Extensor digiti minimi Extensor carpi ulnaris.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 22-year-old female presented with an injury over the wrist after a fight with his husband. The doctor on duty in the emergency department realizes that the structure given in the image shown below is not damaged and the cut is superficial. Which of the following structures given in the option are least prone to injury?", "options": [{"label": "A", "text": "Ulnar Nerve", "correct": false}, {"label": "B", "text": "Ulnar Artery", "correct": false}, {"label": "C", "text": "Median Nerve", "correct": true}, {"label": "D", "text": "Superficial branch of radial nerve", "correct": false}], "correct_answer": "C. Median Nerve", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683156588-QTDA100003IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Median Nerve In the given question, the female with superficial cuts around the wrist and the given image showing the flexor retinaculum which is not damaged suggest the injury is superficial. Hence the structure deep into the flexor retinaculum will not be damaged. The median nerve passes deep into the flexor retinaculum. Hence, the answer to this question will be the median nerve as it lies deep in the flexor retinaculum. So the answer will be option C</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Ulnar Nerve Option: B. Ulnar artery The ulnar nerve and artery both pass superficial to the flexor retinaculum, so are more prone to injury in case of a superficial cut. Structure passing about Flexor Retinaculum Option: D. Superficial branch of radial nerve The superficial branch of the radial nerve passes superficially in the anatomical snuff box, not related to the flexor retinaculum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The given image shows the lower end of the radius showing the dorsal tubercle of the lister. Which of the following compartment of the extensor retinaculum does it divide?", "options": [{"label": "A", "text": "1st and 2nd", "correct": false}, {"label": "B", "text": "2nd and 3rd", "correct": true}, {"label": "C", "text": "3rd and 4th", "correct": false}, {"label": "D", "text": "4th and 5th", "correct": false}], "correct_answer": "B. 2nd and 3rd", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683156612-QTDA100004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2nd and 3rd In the given question, the dorsal tubercle of the lister divides the 2nd and 3rd compartments of the extensor retinaculum , as shown in the image given below. Lister tubercle in relation to Extensor Compartment</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options A, B, and D. are not separated by lister tubercle nearby as shown in the image above.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The following image shows the dorsal aspect of the wrist which shows the following structure. Arrange the following structure in the correct sequence from medial to lateral in the compartment of the given structure. Tendon of ECRL and ECRB EPL Anterior interosseous artery Extensor indicis Extensor digit minimi Abductor pollicis longus and extensor pollicis brevis. Select the correct answer from below code:", "options": [{"label": "A", "text": "5->4,3->2->1->6", "correct": true}, {"label": "B", "text": "6->1->2->4,3->5", "correct": false}, {"label": "C", "text": "1->2->3,4->5->6", "correct": false}, {"label": "D", "text": "6->1->2,3->4->5", "correct": false}], "correct_answer": "A. 5->4,3->2->1->6", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683156644-QTDA100005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>5->4,3->2->1->6 In the given question, the market structure is the extensor The structure from medial to lateral arranged in the compartment will be: 6th Compartment-Extensor Carpi Ulnaris 5th compartment- extensor digit minimi 4th compartment- an anterior interosseous artery and extensor indicis 3rd compartment- EPL 2nd compartment- tendons of ECRL and ECRB 1st compartment- abductor pollicis longus and extensor pollicis brevis. Hence, the correct sequence will be as option A. 5->4,3->2->1->6.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 58-year-old female with a history of Diabetes Mellitus for the past 10 years now presents with pain around the wrist joint, especially at night. She also says that she feels a tingling sensation around the tip of the thumb, index, and ring fingers. On examination, the doctor performed a test that involved compression over the wrist which produced similar symptoms like the night pains. Which of the following structure in the given image is compressed?", "options": [{"label": "A", "text": "2", "correct": true}, {"label": "B", "text": "1", "correct": false}, {"label": "C", "text": "3", "correct": false}, {"label": "D", "text": "4", "correct": false}], "correct_answer": "A. 2", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/questionImage-1690539382316-QTDA100006.jpg"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2 In the given question, the patient presented with the symptoms of carpal tunnel syndrome which occurs due to compression of the median nerve beneath the flexor retinaculum. The test performed by the doctor is Durkan’s test which is the most specific test for this condition. Hence, as asked in the question, the structure affected lies beneath the flexor retinaculum. Marked structures are as follows: Ulnar nerve and Ulnar artery Median nerve Flexor Retinaculum Flexor digitorum profundus tendon Hence, the answer to this question is option B.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "To which of the following structures does the Superior extensor retinaculum bind down the tendons of tibialis anterior, extensor hallucis longus, extensor digitorum longus, and fibularis tertius?", "options": [{"label": "A", "text": "The upper surface of the calcaneus, anterior to the calcaneal sulcus.", "correct": false}, {"label": "B", "text": "Medial malleolus.", "correct": false}, {"label": "C", "text": "The lateral surface of the calcaneus.", "correct": false}, {"label": "D", "text": "The anterior aspect of the ankle joint", "correct": true}], "correct_answer": "D. The anterior aspect of the ankle joint", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The anterior aspect of the ankle joint The superior extensor retinaculum binds down the tendons of tibialis anterior, extensor hallucis longus, extensor digitorum longus, and fibularis tertius immediately proximal to the anterior aspect of the ankle joint.</p>\n<p><strong>Random:</strong></p><p>' Explanation for Incorrect Options:- Option A - The inferior extensor retinaculum is a Y-shaped band lying anterior to the ankle joint. The stem of the Y is at the lateral end, where it is attached to the upper surface of the calcaneus , anterior to the calcaneal sulcus . Option B - The flexor retinaculum is attached anteriorly to the medial malleolus , distal to which it is continuous with the deep fascia on the dorsum of the foot. Option C - The inferior fibular retinaculum is continuous in front with the inferior extensor retinaculum , and is attached posteriorly to the lateral surface of the calcaneus .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following structures is superficial to the superior extensor retinaculum?", "options": [{"label": "A", "text": "Tendon of extensor digitorum longus", "correct": false}, {"label": "B", "text": "Tendon of Extensor hallucis longus", "correct": false}, {"label": "C", "text": "Superficial fibular nerve", "correct": true}, {"label": "D", "text": "Anterior tibial vessel", "correct": false}], "correct_answer": "C. Superficial fibular nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superficial fibular nerve The superficial fibular nerve (superficial peroneal nerve) begins at the bifurcation of the common fibular nerve . It lies deep to fibularis longus at first, then passes anteroinferiorly between fibularis longus and brevis and extensor digitorum longus, and pierces the deep fascia in the distal third of the leg. It divides into a large medial dorsal cutaneous nerve and a smaller, more laterally placed, intermediate dorsal cutaneous nerve, usually after piercing the deep fascia, but sometimes while it is still deep into the fascia. As the nerve lies between the muscles it supplies fibularis longus, fibularis brevis, and the skin of the lower leg. It passes the superficial to the superior extensor retinaculum.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - Extensor digitorum longus arises from the inferior surface of the lateral condyle of the tibia, the proximal three-quarters of the medial surface of the fibula, the adjacent anterior surface of the interosseous membrane , the deep surface of the deep fascia, the anterior intermuscular septum and the fascial septum between itself and tibialis anterior . These origins form the walls of an Osseo aponeurotic tunnel . The extensor digitorum longus becomes tendinous at about the same level as tibialis anterior , and the tendon passes deep to the superior extensor retinaculum . Option B - Extensor hallucis longus lies between, and is partly overlapped by, tibialis anterior and extensor digitorum longus. It arises from the middle half of the medial surface of the fibula, medial to extensor digitorum longus , and from the adjacent anterior surface of the interosseous membrane. Its fibres run distally and end in a tendon that forms on the anterior border of the muscle. The tendon passes deep to the superior extensor retinaculum. Option D - Anterior tibial vessel Structure passes deep to superior extensor retinacula Anterior tibial vessels and deep fibular nerve Tendon of extensor digitorum longus Tendon of extensor hallucis longus</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Superior extensor retinaculum laterally blends with which structure?", "options": [{"label": "A", "text": "Deep fascia of the leg.", "correct": false}, {"label": "B", "text": "Dense connective tissue.", "correct": false}, {"label": "C", "text": "Superior fibular retinaculum", "correct": true}, {"label": "D", "text": "The upper border of the extensor retinaculum.", "correct": false}], "correct_answer": "C. Superior fibular retinaculum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior fibular retinaculum Laterally, it blends with the superior fibular retinaculum</p>\n<p><strong>Highyeild:</strong></p><p>FLEXOR RETINACULUM</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options:- Option A - Proximal border is continuous with the deep fascia of the leg. Option B - Dense connective tissue connects its distal border to the inferior extensor retinaculum . Option D - medially with the upper border of the extensor retinaculum .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which structure passes deep to the flexor retinaculum?", "options": [{"label": "A", "text": "Tendon of extensor digitorum longus", "correct": false}, {"label": "B", "text": "Tendon of Extensor hallucis longus", "correct": false}, {"label": "C", "text": "Superficial fibular nerve", "correct": false}, {"label": "D", "text": "Tibialis posterior", "correct": true}], "correct_answer": "D. Tibialis posterior", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tibialis posterior The tibialis posterior passes deep to the flexor retinaculum and superficial to the deltoid ligament to enter the foot . In the foot, it is at first inferior to the plantar calcaneonavicular ligament, where it contains sesamoid fibrocartilage.</p>\n<p><strong>Highyeild:</strong></p><p>FLEXOR RETINACULUM</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: Option A - Extensor digitorum longus arises from the inferior surface of the lateral condyle of the tibia, the proximal three-quarters of the medial surface of the fibula, the adjacent anterior surface of the interosseous membrane, the deep surface of the deep fascia, the anterior intermuscular septum and the fascial septum between itself and tibialis anterior. These origins form the walls of an Osseo aponeurotic tunnel. The extensor digitorum longus becomes tendinous at about the same level as tibialis anterior , and the tendon passes deep to the superior extensor retinaculum . Option B - Extensor hallucis longus lies between, and is partly overlapped by, tibialis anterior and extensor digitorum longus . It arises from the middle half of the medial surface of the fibula, medial to extensor digitorum longus, and from the adjacent anterior surface of the interosseous membrane. Its fibers run distally and end in a tendon that forms on the anterior border of the muscle. The tendon passes deep to the superior extensor retinaculum. Option C- Superficial fibular nerve - The superficial fibular nerve (superficial peroneal nerve) begins at the bifurcation of the common fibular nerve. It lies deep to fibularis longus at first, then passes Antero inferiorly between fibularis longus and brevis and extensor digitorum longus, and pierces the deep fascia in the distal third of the leg. It divides into a large medial dorsal cutaneous nerve and a smaller, more laterally placed, intermediate dorsal cutaneous nerve, usually after piercing the deep fascia, but sometimes while it is still deep into the fascia. As the nerve lies between the muscles it supplies fibularis longus, fibularis brevis, and the skin of the lower leg. It passes superficial to the superior extensor retinacula.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following extensor tendons possess synovial sheath at the level of superior extensor retinaculum?", "options": [{"label": "A", "text": "Tendon of tibialis anterior", "correct": true}, {"label": "B", "text": "Tendon of fibularis longus", "correct": false}, {"label": "C", "text": "Tendon of fibularis brevis", "correct": false}, {"label": "D", "text": "Tendon of extensor digitorum longus", "correct": false}], "correct_answer": "A. Tendon of tibialis anterior", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tendon of tibialis anterior The tendon of the tibialis anterior is the only extensor tendon that possesses a synovial sheath at the level of the superior extensor retinaculum .</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options: Fibularis longus is the more superficial of the two muscles of the lateral compartment. It arises from the head and proximal two-thirds of the lateral surface of the fibula, the deep surface of the deep fascia, the anterior and posterior intermuscular septa , and occasionally by a few fibers from the lateral condyle of the tibia. The muscle belly ends in a long tendon that runs distally behind the lateral malleolus in a groove it shares with the tendon of fibularis brevis. The groove is converted into a canal by the superior fibular retinaculum, such that the tendon of fibularis longus and that of fibularis brevis, which lies in front of the longus tendon, are contained in a common synovial sheath. Option B - Extensor hallucis longus lies between, and is partly overlapped by, tibialis anterior and extensor digitorum longus . It arises from the middle half of the medial surface of the fibula, medial to extensor digitorum longus, and from the adjacent anterior surface of the interosseous membrane. Its fibers run distally and end in a tendon that forms on the anterior border of the muscle. The tendon passes deep to the superior extensor retinaculum and it does not form a synovial sheath at the level of the superior extensor retinacula. Option C - Fibularis brevis arises from the distal two-thirds of the lateral surface of the fibula, anterior to fibularis longus, and from the anterior and posterior crural intermuscular septa. It passes vertically downwards and ends in a tendon that passes behind the lateral malleolus together with, and anterior to, that of fibularis longus. The two tendons run deep to the superior fibular retinaculum in a common synovial sheath. Option D - Extensor digitorum longus arises from the inferior surface of the lateral condyle of the tibia, the proximal three-quarters of the medial surface of the fibula, the adjacent anterior surface of the interosseous membrane, the deep surface of the deep fascia, the anterior intermuscular septum and the fascial septum between itself and tibialis anterior. These origins form the walls of an Osseo aponeurotic tunnel. The extensor digitorum longus becomes tendinous at about the same level as the tibialis anterior, and the tendon passes deep to the superior extensor retinaculum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which retinacula converts the groove into a canal which is run by the long tendon of fibularis longus?", "options": [{"label": "A", "text": "Superior Fibular Retinaculum", "correct": true}, {"label": "B", "text": "Inferior fibular retinaculum", "correct": false}, {"label": "C", "text": "Superior extensor retinaculum", "correct": false}, {"label": "D", "text": "Flexor retinaculum", "correct": false}], "correct_answer": "A. Superior Fibular Retinaculum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior Fibular Retinaculum The Fibularis longus is the more superficial of the two muscles of the lateral compartment . It arises from the head and proximal two-thirds of the lateral surface of the fibula, the deep surface of the deep fascia, the anterior and posterior intermuscular septa, and occasionally by a few fibers from the lateral condyle of the tibia. Fibularis longus belly ends in a long tendon that runs distally behind the lateral malleolus in a groove it shares with the tendon of the fibularis brevis . The groove is converted into a canal by the superior fibular retinaculum.</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options: Option B - Inferior fibular retinaculum. The inferior fibular retinaculum is continuous in front with the inferior extensor retinaculum, and is attached posteriorly to the lateral surface of the calcaneus. Some of its fibers are fused with the periosteum on the fibular trochlea (peroneal trochlea or tubercle) of the calcaneus, forming a septum between the tendons of fibularis longus and brevis Option C -The superior extensor retinaculum is attached laterally to the distal end of the anterior border of the fibula and medially to the anterior border of the tibia. Its proximal border is continuous with the deep fascia of the leg, and dense connective tissue connects its distal border to the inferior extensor retinaculum. Laterally, it blends with the superior fibular retinaculum and medially with the upper border of the extensor retinaculum. Option D - The flexor retinaculum is attached anteriorly to the medial malleolus, distal to which it is continuous with the deep fascia on the dorsum of the foot. From its malleolar attachment, it extends posteroinferiorly to the medial process of the calcaneus and the plantar aponeurosis. Proximally, there is no clear demarcation between its border and the deep fascia of the leg, especially the deep transverse layer of the deep fascia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Find out the wrong statement with respect to the inferior extensor retinaculum.", "options": [{"label": "A", "text": "The inferior retinaculum is a Y shaped band", "correct": false}, {"label": "B", "text": "The stem of the Y is at the lateral end", "correct": false}, {"label": "C", "text": "Loop around the tendons of fibularis tertius and extensor digitorum longus", "correct": false}, {"label": "D", "text": "The deep layer passes superficial to the tendons of extensor hallucis longus and tibialis anterior", "correct": true}], "correct_answer": "D. The deep layer passes superficial to the tendons of extensor hallucis longus and tibialis anterior", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The deep layer passes superficial to the tendons of extensor hallucis longus and tibialis anterior The i nferior extensor retinaculum of the foot is a Y-shaped band placed in front of the ankle-joint , the stem of the Y is attached laterally to the upper surface of the calcaneus , in front of the depression for the interosseous talocalcaneal ligament . The inferior extensor retinaculum is directed medialward as a double layer, one lamina passing in front of, and the other behind, the tendons of the peroneus tertius and extensor digitorum longus .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: Option A- The inferior extensor retinaculum is a Y-shaped band lying anterior to the ankle joint Option B - The stem of the Y is at the lateral end, where it is attached to the upper surface of the calcaneus, anterior to the calcaneal sulcus. Option C- Band passes medially, forming a strong loop around the tendons of fibularis tertius and extensor digitorum longus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "True about the extent of foregut:", "options": [{"label": "A", "text": "Structures of gastrointestinal tract till major duodenal papilla", "correct": true}, {"label": "B", "text": "Structures from major duodenal papilla to junction between right 2/3rd to left 1/3rd Transverse colon", "correct": false}, {"label": "C", "text": "Structures from left 1/3rd Transverse colon to the cloacal membrane", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Structures of gastrointestinal tract till major duodenal papilla", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Structures of gastrointestinal tract till major duodenal papilla The foregut extends from the esophagus to the duodenum at the level of the major duodenal papilla where the pancreatic and common bile duct insert, and it consists of the esophagus, stomach, the proximal duodenum, as well as the liver, gallbladder, pancreas and spleen.</p>\n<p><strong>Highyeild:</strong></p><p>Endoderm forms the epithelial lining of the digestive tract and gives rise to the specific cells (the parenchyma) of glands, such as hepatocytes and the exocrine and endocrine cells of the pancreas.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B . Structures from major duodenal papilla to junction between right 2/3rd to left 1/3rd Transverse colon Midgut includes structures from major duodenal papilla to junction between right 2/3rd to left 1/3rd Transverse colon. Option C .Structures from left 1/3rd Transverse colon to the cloacal membrane The Hindgut includes structures from the left 1/3rd Transverse colon to the cloacal membrane. Option D . none of the above The foregut extends from the esophagus to the duodenum at the level of the major duodenal papilla where the pancreatic and common bile duct insert, so Option D is incorrect answer.</p>\n<p><strong>Extraedge:</strong></p><p>The stroma (connective tissue) for the glands is derived from visceral mesoderm. Muscle, connective tissue, and peritoneal components of the wall of the gut also are derived from visceral mesoderm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Foregut receives its blood supply from which of the following source:", "options": [{"label": "A", "text": "Celiac Trunk", "correct": true}, {"label": "B", "text": "Superior mesenteric artery", "correct": false}, {"label": "C", "text": "Inferior mesenteric artery", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Celiac Trunk", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The Celiac Trunk Celiac plexus is a plexus of nerves around the celiac trunk. Foregut receives blood supply from the celiac trunk arising from T12 level of abdominal aorta.</p>\n<p><strong>Highyeild:</strong></p><p>Initially, the foregut, midgut, and hindgut are in broad contact with the mesenchyme of the posterior abdominal wall. By the fifth week, however, this connecting tissue bridge has narrowed, and the caudal part of the foregut, the midgut, and a major part of the hindgut are suspended from the abdominal wall by the dorsal mesentery. Primitive dorsal and ventral mesenteries</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. superior mesenteric artery Superior mesenteric artery arising from L1 level supplies midgut. Option C. inferior mesenteric artery Inferior mesenteric artery arising from L3 level supplies hindgut. Option D. none of the above Foregut receives blood supply from the celiac trunk arising from T12 level of abdominal aorta, and hence d) none of the above cannot be the answer.</p>\n<p><strong>Extraedge:</strong></p><p>The mesentery is a collection of connective tis- sues that maintains the gut tube and its derivatives in their normal anatomical positions. In the abdomen, dorsal mesentery extends from the lower portion of the esophagus to the rectum as a continuous sheet of tissue attached to the posterior body wall and providing a path- way for blood vessels, lymphatics, and nerves to the gut tube and its derivatives.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The Hepatoduodenal ligament is formed from which of the following:", "options": [{"label": "A", "text": "Ventral Mesogastrium", "correct": true}, {"label": "B", "text": "Dorsal mesogastrium", "correct": false}, {"label": "C", "text": "Left layer of dorsal mesogastrium\\", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Ventral Mesogastrium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ventral Mesogastrium Falciform ligament is also formed from ventral mesogastrium. The ventral mesentery between the liver and the stomach will develop into the gastrohepatic and hepatoduodenal ligaments. Hepatoduodenal ligament is a part of lesser omentum and arises from ventral mesogastrium.</p>\n<p><strong>Highyeild:</strong></p><p>Derivatives of Ventral and Dorsal mesogastrium</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B . dorsal mesogastrium Greater omentum , gastrosplenic ligament,lienorenal ligament, gastrosplenic ligaments develops from dorsal mesogastrium Option C. A left layer of dorsal mesogastrium Left layer of dorsal mesogastrium gives rise to spleen Option D. The none of the above Hepatoduodenal ligament is a part of lesser omentum and arises from ventral mesogastrium and hence d) none of the above is incorrect answer.</p>\n<p><strong>Extraedge:</strong></p><p>The Ventral mesentery is derived from mesenchyme of the septum transversum. Growth of the liver into the septum divides the ventral mesentery into (1) the ventral mesogastrium (lesser omentum) extending from the stomach and proximal most part of the duodenum to the liver and (2) the falciform ligament extending from the liver to the ventral body wall.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 58-year-old male with a history of pancreatitis presented with abdominal pain. MRCP was negative for CBD dilatation and gallstones. CT scan revealed failure of anastomosis in the duct system. The patient was diagnosed with the most common anomaly of pancreas, what is it?", "options": [{"label": "A", "text": "Pancreatic Divisum", "correct": true}, {"label": "B", "text": "Annular pancreas", "correct": false}, {"label": "C", "text": "Both A & B", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Pancreatic Divisum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pancreatic Divisum Pancreatic divisum is a congenital anomaly in which a single pancreatic duct is not formed, but rather remains as two distinct dorsal and ventral ducts. Pancreatic divisum is also a cause of acute pancreatitis.</p>\n<p><strong>Highyeild:</strong></p><p>Pancreatic divisum is a congenital anomaly in the anatomy of the ducts of the pancreas in which a single pancreatic duct is not formed, but rather remains as two distinct dorsal and ventral ducts. Most individuals with pancreas divisum remain without symptoms or complications. A minority of people with pancreatic divisum may develop episodes of abdominal pain, nausea or vomiting due to acute or chronic pancreatitis. The human embryo begins life with two ducts in the pancreas, the ventral duct and the dorsal duct. Normally, the two ducts will fuse together to form one main pancreatic duct; this occurs in more than 90% of embryos. In approximately 10% of embryos the ventral and dorsal ducts fail to fuse together, resulting in pancreas divisum.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B . Annular pancreas Annular pancreas results from growth of a bifid ventral pancreatic bud around the duodenum, where the parts of the bifid ventral bud fuse with the dorsal bud, forming a pancreatic ring and is less common than pancreatic divisum. Option C . Both A & B Option D . None of the above Annular pancreas results from growth of a bifid ventral pancreatic bud around the duodenum, where the parts of the bifid ventral bud fuse with the dorsal bud, forming a pancreatic ring and is less common than pancreatic divisum. Pancreatic divisum is a congenital anomaly in which a single pancreatic duct is not formed, but rather remains as two distinct dorsal and ventral ducts.Pancreatic divisum is also a cause of acute pancreatitis.</p>\n<p><strong>Extraedge:</strong></p><p>Annular pancreas : In this condition, the pancreatic tissue completely surrounds the second part of the duode- num causing its obstruction. This anomaly is produced as follows: The bifid ventral pancreatic bud fails to fuse to form a single mass. The two lobes (right and left) of the ventral pancreatic bud grow and migrate in opposite directions around the second part of the duodenum and form a collar of pancreatic tissue before it fuses with the dorsal pancreatic bud. Thus, duodenum gets completely surrounded by the pancreatic tissue that may cause duodenal obstruction. Clinical Features Option A: Vomiting may start a few hours after birth. Option B: Radiograph of abdomen reveals double–bubble appear- ance. It is associated with duodenal stenosis. It is due to gas in the stomach and dilated part of the duodenum proximal to the site of obstruction. Early surgical intervention to relieve the obstruction is necessary. The surgical procedure consists of duodenum– jejunostomy and not cutting of the pancreatic collar.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The marked area of the pancreas is formed from which of the following structure?", "options": [{"label": "A", "text": "Ventral Pancreatic Bud", "correct": true}, {"label": "B", "text": "Dorsal pancreatic bud", "correct": false}, {"label": "C", "text": "Hepatic bud", "correct": false}, {"label": "D", "text": "Respiratory bud", "correct": false}], "correct_answer": "A. Ventral Pancreatic Bud", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682567265-QTDA079005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ventral Pancreatic Bud The marked structure in the image above is an uncinate process of the pancreas which develops from the ventral pancreatic bud. Ventral pancreatic bud also forms a part of the head of the pancreas.</p>\n<p><strong>Highyeild:</strong></p><p>The pancreas develops from two endodermal pancreatic buds that arise from the junction of the foregut and midgut. The dorsal bud forms the upper part of the head, neck, body, and tail of the pancreas while ventral bud forms the lower part of the head and uncinate process. The main pancreatic duct is formed by the distal three-fourth of the duct of dorsal bud and proximal one-fourth of the duct of the ventral bud. The accessory pancreatic duct is formed by proximal one-fourth of the duct of the dorsal pancreatic bud. Derivation of various parts of pancreas from dorsal and ventral pancreatic buds.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B: dorsal pancreatic bud gives rise to upper part of head, body and tail of pancreas Option C: hepatic bud gives rise to biliary apparatus and hepatocytes of liver Option D: respiratory bud forms the lining of respiratory epithelium</p>\n<p><strong>Extraedge:</strong></p><p>Accessory pancreatic tissue may be anywhere from the distal end of the esophagus to the tip of the primary intestinal loop. Most frequently, it lies in the mucosa of the stomach and in Meckel diverticulum, where it may show all of the histological characteristics of the pancreas itself.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Radio imaging of a newborn infant is done who displays wheezing respiration, which is aggravated when she feeds, flexes her neck, and/or cries, shows double aortic arch compressing her trachea and esophagus. This rare developmental defect results from persistence of the right dorsal aorta, which normally disappears. The arch of the aorta arises from which of the following structures?", "options": [{"label": "A", "text": "Fifth pair of aortic arches", "correct": false}, {"label": "B", "text": "Fourth pair of aortic arches", "correct": true}, {"label": "C", "text": "Second pair of aortic arches", "correct": false}, {"label": "D", "text": "Sixth pair of aortic arches", "correct": false}], "correct_answer": "B. Fourth pair of aortic arches", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fourth pair of aortic arches The arch of the aorta is derived from the ventral part of the aortic sac, its left horn, and the left fourth arch artery . The arch of the aorta is formed from the left fourth aortic arch. Part of the right fourth aortic arch becomes the proximal portion of the right subclavian artery, whereas the rest of the fourth arch disappears. However, if it persists, a right aortic arch is formed passing posterior to the trachea and esophagus. With the formation of the normally occurring left aortic arch, which runs anterior to the trachea and esophagus, a double aortic arch is created. This defect clamps the trachea and esophagus resulting in the respiratory symptoms.</p>\n<p><strong>Highyeild:</strong></p><p>Source of development of main arteries Arteries Source of development Arch of aorta (a) Aortic sac (ventral part), (b) left horn of aortic sac, and (c) left fourth arch artery Brachiocephalic artery Right horn of aortic sac Right subclavian artery Proximal part from right fourth arch artery and (b) distal part from right seventh cervical intersegmental artery Left subclavian artery Left seventh cervical intersegmental artery Common carotid artery Third arch artery proximal to the external carotid artery bud Internal carotid artery Third arch artery distal to the external carotid bud and cranial part of dorsal aorta distal to the attachment of third arch artery External carotid artery Bud from third arch artery Pulmonary arteries Part of the sixth arch artery between pulmonary trunk and branch to lung bud on each side Descending aorta (a) Proximal part from left dorsal aorta distal to attachment of fourth arch artery and (b) distal part from fused dorsal aortae forming single median artery</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: C. The second pair of aortic arches partially form the stapedial arteries in the middle ear of the embryo. The third pair of aortic arches form the common carotid arteries and contribute to the internal carotid arteries. Option: A. The fifth pair of aortic arches either does not develop or form primitive vessels, which disappear eventually. Option: D. The sixth pair of aortic arches contribute to the formation of the pulmonary arteries and ductus arteriosus– Remnant of Ductus arteriosus forms ligamentum arteriosum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "All are true about the following image except:", "options": [{"label": "A", "text": "The above given condition is called Gastroschisis", "correct": true}, {"label": "B", "text": "The above given condition is known as omphalocele", "correct": false}, {"label": "C", "text": "It is due to failure of reduction of physiological hernia of the midgut", "correct": false}, {"label": "D", "text": "It is associated with multiple anomalies", "correct": false}], "correct_answer": "A. The above given condition is called Gastroschisis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682604735-QTDA080001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The above given condition is called Gastroschisis The above condition is known as omphalocele / exomphalos. Gastroschisis is not covered by membranes. Omphalocele anomaly results from failure of coils of the small intestine to return into the abdominal cavity from their physiological herniation into extraembryonic celom during the sixth to tenth week of IUL. It occurs in 2.5/10,000 births and could be associated with cardiac and neural tube defects. Clinically, it presents as a rounded mass protruding from the umbilicus. This mass contains coils of the small intestine and is covered by a transparent amniotic membrane.</p>\n<p><strong>Highyeild:</strong></p><p>Gastroschisis: In this anomaly, there is a linear defect in the anterior abdominal wall through which abdominal contents herniate out. It occurs lateral to the umbilicus, usually on to the right. This defect is produced when lateral folds of the embryo fail to fuse with each other around the connecting stalk. Omphalocele and Gastroschisis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. The above - given condition is known as omphalocele The above condition is known as omphalocele / exomphalos that occurs due to failure to reduce physiological hernia of the midgut. Option C. It is due to failure of reduction of physiological hernia of the midgut Omphalocele anomaly results from failure of coils of the small intestine to return into the abdominal cavity from their physiological herniation into extraembryonic celom during the sixth to tenth week of IUL. It occurs in 2.5/10,000 births and could be associated with cardiac and neural tube defects. Option D. It is associated with multiple anomalies Omphalocele anomaly results from failure of coils of the small intestine to return into the abdominal cavity from their physiological herniation into extraembryonic celom during the sixth to tenth week of IUL . It occurs in 2.5/10,000 births and could be associated with cardiac and neural tube defects.</p>\n<p><strong>Extraedge:</strong></p><p>Omphalocele occurs in 2.5/10,000 births and is associated with a high rate of mortality [25%] and severe malformations, such as cardiac anomalies [50%] and neural tube defects [40%]. Approximately 15% of live-born infants with omphalocele have chromosomal abnormalities.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the condition from the following image, which 2-year-old Rahul was suffering from:", "options": [{"label": "A", "text": "Vitelline Fistula", "correct": false}, {"label": "B", "text": "vitelline sinus", "correct": false}, {"label": "C", "text": "Meckel's diverticulum", "correct": true}, {"label": "D", "text": "vitelline cyst", "correct": false}], "correct_answer": "C. Meckel's diverticulum", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682604767-QTDA080002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Meckel's diverticulum The above given image is of Meckel’s diverticulum which is due to persistence of the proximal vitellointestinal duct. Meckel’s diverticulum : A small part of the vitellointestinal duct close to midgut (ileum) persists and forms Meckel's diverticulum. It may be connected to the umbilicus by a fibrous cord (the obliterated remaining part of the vitellointestinal duct).</p>\n<p><strong>Highyeild:</strong></p><p>Meckel’s diverticulum is a small diverticulum arising from the antimesenteric border of the ileum; it is about 2 inches (5 cm) in length, is present about 2 feet (60 cm) proximal to an ileocecal junction, and occurs in about 2% of people. It may contain gastric mucosa or pancreatic tissue. There might be ulceration, bleeding, or even perforation of Meckel’s diverticulum. It may undergo inflammation, symptoms of which may mimic that of appendicitis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Vitelline Fistula Vitelline fistula is due to a patent vitellointestinal duct. Option B. vitelline sinus Vitelline sinus is a persistent omphalomesenteric sinus Option D. vitelline cyst A vitelline cyst is the cyst of persistent vitellointestinal duct Vitellointestinal duct anomalies</p>\n<p><strong>Extraedge:</strong></p><p>The vitelline duct remains patent over its entire length, forming a direct communication between the umbilicus and the intestinal tract. This abnormality is known as an umbilical fistula, or a vitelline fistula. A fecal discharge may then be found at the umbilicus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about rotations of midgut :", "options": [{"label": "A", "text": "180 degree anticlockwise +last 90-degree rotation does not take place", "correct": false}, {"label": "B", "text": "270 degree anticlockwise", "correct": true}, {"label": "C", "text": "90 degree anticlockwise", "correct": false}, {"label": "D", "text": "90 degree clockwise", "correct": false}], "correct_answer": "B. 270 degree anticlockwise", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>270 degree anticlockwise When we view the midgut loop from the ventral aspect, it makes a rotation of 270° in the counterclockwise direction around the axis of the superior mesenteric artery. During rotation also, elongation of the intestinal loop and coiling of the jejunum and ileum takes place. The large intestine also shows elongation but without coiling. The total rotation of the midgut can be divided into three stages, each 90°. A 90° rotation occurs during the herniation and the remaining 180° during the return of the intestinal loop into the abdominal cavity.</p>\n<p><strong>Highyeild:</strong></p><p>Nondevelopment of nerve plexuses in the wall of a part of the intestinal tract may result in difficulty in the passage of intestinal contents through the part. Such a defect in the lower part of the colon gives rise to a condition in which the colon proximal to the defective segment becomes greatly distended with its contents. This condition is called megacolon or Hirschsprung’s disease.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. 180 degree anticlockwise +last 90-degree rotation does not take place Partial rotation: In this anomaly, the first 180° of rotation takes place normally, but the last 90° of rotation does not take place. As a result, the cecum and appendix, instead of being on the right side of the abdominal cavity, are located just below the pylorus of the stomach. Option C. 90 degree anticlockwise Occasionally, however, rotation amounts to 90° only. When this occurs, the colon and cecum are the first portions of the gut to return from the umbilical cord, and they settle on the left side of the abdominal cavity. The later returning loops then move more and more to the right, resulting in a left-sided colon. Option D. 90-degree Clockwise Reversed rotation of the intestinal loop occurs when the primary loop rotates 90° clockwise. In this abnormality, the transverse colon passes behind the duodenum and lies behind the superior mesenteric artery.</p>\n<p><strong>Extraedge:</strong></p><p>Situs inversus - In this condition, all abdominal and thoracic viscera are laterally transposed, i.e. all parts normally on the right side are seen on the left side, and vice versa. For example, the appendix and duodenum lie on the left side, and the stomach on the right side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Midgut consists of all of the following structures except :", "options": [{"label": "A", "text": "Appendix", "correct": false}, {"label": "B", "text": "Cecum", "correct": false}, {"label": "C", "text": "Ascending colon", "correct": false}, {"label": "D", "text": "Transverse colon", "correct": true}], "correct_answer": "D. Transverse colon", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Transverse colon The transverse colon is not completely a midgut derivative. It is partly derived from the midgut (right two-thirds of the transverse colon) and hindgut (left one-third of the transverse colon).</p>\n<p><strong>Highyeild:</strong></p><p>Derivatives of Foregut Prelaryngeal part: Part of the floor of the mouth, including the tongue – Pharynx Salivary glands Various derivatives of the pharyngeal pouches and the thyroid Respiratory system. Post Laryngeal part: Esophagus Stomach Duodenum: Whole of the superior (first) part and upper half of the descending (second) part (up to the major duodenal papilla) Liver and extrahepatic biliary system Pancreas. Derivatives of Midgut Pre Arterial segment Duodenum: Descending (second) part distal to the major papilla; horizontal (third) and ascending (fourth) parts. Jejunum Ileum except for the terminal part. Post Arterial segment: Terminal ileum Cecum and appendix Ascending colon Right two-thirds of the transverse colon. Derivatives of Hindgut Pre Allantoic part: Left one-third of the transverse colon Descending colon Pelvic/sigmoid colon. Post Allantoic part : It forms a dilated endodermal cloaca which is divided by urorectal septum into a dorsal part (primitive rectum) and a ventral part (primitive urogenital sinus). Rectum The upper part of the anal canal Parts of the urogenital system are derived from the primitive urogenital sinus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options A, B & C are all part of the midgut. The foregut extends from the esophagus to the duodenum at the level of the major duodenal papilla, where the pancreatic and common bile duct insert, consisting of the esophagus, stomach, the proximal duodenum, as well as the liver, gallbladder, pancreas and spleen. Foregut is supplied by the celiac trunk.</p>\n<p><strong>Extraedge:</strong></p><p>Arteries of the Gut The celiac artery is the artery of the foregut. It supplies the gut from the lower part of the esophagus to the middle of the duodenum. The superior mesenteric artery is the artery of the midgut. The inferior mesenteric artery is the artery of the hindgut.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A physiological hernia occurs at which week of intrauterine life?", "options": [{"label": "A", "text": "6th Week", "correct": true}, {"label": "B", "text": "10th week", "correct": false}, {"label": "C", "text": "14th week", "correct": false}, {"label": "D", "text": "16th week", "correct": false}], "correct_answer": "A. 6th Week", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>6th Week A physiological hernia occurs in the 6th week of intrauterine life. Failure of return of physiological hernia can result in omphalocele. It occurs because the bowel (particularly the ileum) grows faster than the abdominal cavity during the early gestational period. In this physiological situation, the intestine elongates and moves out of the embryonic abdomen herniating into the base of the umbilical cord.</p>\n<p><strong>Highyeild:</strong></p><p>Physiological Herniation Development of the primary intestinal loop is characterized by rapid elongation,particularly the cephalic limb. As a result of the rapid growth and expansion of the liver, the abdominal cavity temporarily becomes too small to contain all the intestinal loops, and they enter the extraembryonic cavity in the umbilical cord during the sixth week of development (physiological umbilical herniation).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Physiological hernia reduces at the 10th week as the abdominal cavity enlarges. Option C. 14 weeks Option D. 16 weeks are all incorrect options.</p>\n<p><strong>Extraedge:</strong></p><p>Retraction of Herniated Loops During the 10th week, herniated intestinal loops begin to return to the abdominal cavity. Although the factors responsible for this return are not precisely known, it is thought that regression of the mesonephric kidney, reduced growth of the liver, and expansion of the abdominal cavity play important roles.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the green arrow marked structure:", "options": [{"label": "A", "text": "Ladd’s Bands", "correct": true}, {"label": "B", "text": "Greater Omentum", "correct": false}, {"label": "C", "text": "Gastrocolic ligament", "correct": false}, {"label": "D", "text": "Splenocolic ligament", "correct": false}], "correct_answer": "A. Ladd’s Bands", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682604799-QTDA080006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ladd’s Bands Green coloured arrow marked structure is Ladd’s band. Ladd's bands, sometimes called bands of Ladd, are fibrous stalks of peritoneal tissue that attach the cecum to the retroperitoneum in the right lower quadrant (RLQ). Obstructing Ladd's Bands are associated with malrotation of the intestine, a developmental disorder in which the cecum is found in the right upper quadrant (RUQ), instead of its normal anatomical position in the RLQ. Ladd's bands then pass over the second part of the duodenum, causing extrinsic compression and obstruction. This clinically manifests as poor feeding and bilious vomiting in neonates. Screening can be performed with an upper GI series.</p>\n<p><strong>Highyeild:</strong></p><p>The most severe complication of malrotation is midgut volvulus, in which the mesenteric base twists around the superior mesenteric artery, compromising intestinal perfusion and leading to bowel necrosis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Greater Omentum The greater omentum is a large apron-like fold of visceral peritoneum that hangs down from the stomach. It extends from the greater curvature of the stomach, passing in front of the small intestines and doubles back to ascend to the transverse colon before reaching to the posterior abdominal wall. Option C. Gastrocolic ligament The gastrocolic ligament is a portion of the greater omentum that stretches from, the greater curvature of the stomach to the transverse colon. It forms part of the anterior wall of the lesser sac. Dividing the gastrocolic ligament provides access to the anterior pancreas and the posterior wall of the stomach. This is commonly done for Whipple procedures, distal pancreatectomy, some forms of the Roux-en-Y gastric bypass, and exploratory laparotomy. Option D. splenocolic ligament The splenocolic ligament is a peritoneal ligament connecting the splenic capsule to the transverse colon. Made of visceral peritoneum, it lies between the greater omentum and the transverse mesocolon. It has three attached borders, superiorly to the spleen, inferiorly to the splenic flexure of the transverse colon and posteriorly to the pancreatic colic ligament, which itself is attached posteriorly to the left kidney, and a free anterior one Of clinical relevance, one cause of exercise-induced pain in one's left side (a side stitch) is stretching of this ligament and the peritoneum when the spleen swells from exertion.</p>\n<p><strong>Extraedge:</strong></p><p>A surgical operation called a \"Ladd procedure\" is performed to alleviate intestinal malrotation. The procedure involves counterclockwise detorsion of the bowel, surgical division of Ladd's bands, widening of the small intestine's mesentery, performing an appendectomy, and reorientation of the small bowel on the right and the cecum and colon on the left (the appendectomy is performed so as not to be confused by atypical presentation of appendicitis at a later date). Most Ladd surgical repairs take place in infancy or childhood.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Pre arterial segment of midgut gives rise to which of the following?", "options": [{"label": "A", "text": "Duodenum", "correct": true}, {"label": "B", "text": "Cecum", "correct": false}, {"label": "C", "text": "Transverse colon", "correct": false}, {"label": "D", "text": "Appendix", "correct": false}], "correct_answer": "A. Duodenum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Duodenum Pre arterial segment of the midgut gives rise to the small intestine. The pre-arterial segment of the midgut loop gives rise to the distal half of the duodenum.</p>\n<p><strong>Highyeild:</strong></p><p>The duodenum develops from two sources (dual origin): (a) the proximal half is derived from the foregut, and (b) the distal half is derived from the midgut. The details are as follows: (a) The first and second part of the duodenum up to the opening of the common bile duct develops from the foregut, and (b) the second part of the duodenum below the opening of the common bile duct along with the third and fourth parts develop from the midgut.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. cecum Cecum arises from the cecal bud of the midgut Option C. transverse colon Ascending colon, transverse colon and descending colon all arise from the post-arterial segment of the midgut. Option D. appendix Appendix arises from appendicular bud of midgut</p>\n<p><strong>Extraedge:</strong></p><p>The pre arterial segment of the midgut loop gives rise to: Distal half of the duodenum Jejunum Ileum, except its terminal part. The post arterial segment of the midgut loop gives rise to: The terminal part of the ileum Cecum Appendix Ascending colon Proximal (right) two-thirds of the transverse colon.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following structure develops from dorsal mesentery?", "options": [{"label": "A", "text": "Greater Omentum", "correct": true}, {"label": "B", "text": "Lesser omentum", "correct": false}, {"label": "C", "text": "Liver", "correct": false}, {"label": "D", "text": "Diaphragm", "correct": false}], "correct_answer": "A. Greater Omentum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Greater Omentum Dorsal Mesentery Derivatives - The dorsal mesogastrium gives rise to a series of ligaments interconnecting the organs in the left upper abdomen: the gastrosplenic, splenorenal, and gastrocolic ligaments and the greater omentum. Ventral Mesentery gives rise to lesser omentum, falciform ligament etc.</p>\n<p><strong>Highyeild:</strong></p><p>Derivatives of Ventral and Dorsal mesogastrium</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Lesser omentum The lesser omentum originates from the ventral mesentery. Option C. Liver Embryonic liver originates from the ventral foregut endoderm Option D. Diaphragm Diaphragm develops from the septum transversum, pleuroperitoneal folds, and the somites and is innervated by the phrenic nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The ventral mesentery is derived from the mesenchyme of the septum transversum. Growth of the liver into the septum divides the ventral mesentery into (1) the ventral mesogastrium (lesser omentum) extending from the stomach and proximal-most part of the duodenum to the liver and (2) the falciform ligament extending from the liver to the ventral body wall.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The given image signifies:", "options": [{"label": "A", "text": "Non-rotation of midgut", "correct": true}, {"label": "B", "text": "Reverse rotation of the midgut", "correct": false}, {"label": "C", "text": "Subhepatic cecum", "correct": false}, {"label": "D", "text": "Partial rotation", "correct": false}], "correct_answer": "A. Non-rotation of midgut", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/questionImage-1689922977010-QTDA080009IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Non-rotation of midgut When the midgut fails to rotate further after the first 90 degrees of counterclockwise rotation, it will lead to the development of a small intestine to the right side and a large intestine (radiograph) to the left side of the abdominal cavity. The condition is known as non-rotation. These rotation anomalies of the gut can occur due to persistent ladd’s band.</p>\n<p><strong>Highyeild:</strong></p><p>Non-rotation : In this anomaly, the midgut loop fails to rotate. The caudal or post arterial segment returns first in the abdominal cavity. Hence, the large intestine occupies the left side of the abdominal cavity while the small intestine derived from pre- arterial segment returns later and occupies the right side of the abdominal cavity. Reversed rotation : In this anomaly, the midgut loop rotates clockwise instead of anticlockwise. In this condition, the transverse colon passes behind the duodenum and lies behind the superior mesenteric artery. Subhepatic cecum and appendix (undescended cecum and appendix) : The cecum develops from a cecum bud—a small conical dilatation that appears in the caudal segment of midgut loop near its apex at about the sixth week of IUL. When the caudal segment of the midgut loop returns to the abdominal cavity, the cecum lies below the liver ( subhepatic position ), as the post-arterial segment of the midgut loop elongates to form ascending colon, the cecum and appendix acquire a definitive position in the right iliac fossa. But if the ascending colon does not form or remains too short, the cecum does not descend and remains permanently below the liver leading to a congenital anomaly called subhepatic cecum and appendix.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Reverse rotation of the midgut Reversed rotation: In this anomaly, the midgut loop rotates clockwise instead of anticlockwise. In this condition, trans- verse colon passes behind the duodenum and lies behind the superior mesenteric artery. Option C. Subhepatic cecum The cecum develops from a cecum bud—a small conical dilatation that appears in the caudal segment of the midgut loop near its apex at about the sixth week of IUL. When the caudal segment of the midgut loop returns to the abdominal cavity, the cecum lies below the liver ( subhepatic position ). As the post arterial segment of midgut loop elongates to form ascending colon, the cecum and appendix acquire a definitive position in the right iliac fossa. But if the ascending colon does not form or remains too short, the cecum does not descend and remains permanently below the liver leading to a congenital anomaly called subhepatic cecum and appendix. Option D. Partial rotation Partial rotation: In this anomaly, the first 180° of rotation takes place normally but the last 90° of rotation does not take place. As a result, the cecum and appendix, instead of being on the right side of the abdominal cavity, are located just below the pylorus of the stomach.</p>\n<p><strong>Extraedge:</strong></p><p>In cases of the subhepatic cecum and appendix, the inflammation of the appendix ( appendicitis ) would cause tenderness in the right hypochondrium, possibly leading to a mistaken diagnosis of chole-cystitis (inflammation of the gallbladder).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Ventral mesogastrium gives rise to:", "options": [{"label": "A", "text": "Lesser Omentum", "correct": true}, {"label": "B", "text": "Greater omentum", "correct": false}, {"label": "C", "text": "Gastrophrenic ligament", "correct": false}, {"label": "D", "text": "Gastrosplenic ligament", "correct": false}], "correct_answer": "A. Lesser Omentum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lesser Omentum Ventral mesogastrium- the primitive midline mesentery extending between the future stomach and proximal duodenum and the anterior abdominal wall superior to the umbilicus (umbilical vein). The liver develops within it; consequently, the lesser omentum, coronary and falciform ligaments are derivatives of it.</p>\n<p><strong>Highyeild:</strong></p><p>The lesser omentum ( small omentum or gastrohepatic omentum ) is the double layer of the peritoneum that extends from the liver to the lesser curvature of the stomach and the first part of the duodenum. The lesser omentum is usually divided into these two connecting parts: the hepatogastric ligament and the hepatoduodenal ligament.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Greater omentum Greater Omentum is derived from dorsal mesogastrium. Option C. Gastrophrenic ligament The gastrophrenic ligament is derived from the dorsal mesogastrium. Option D. Gastrosplenic ligament A gastrosplenic ligament is derived from the dorsal mesogastrium.</p>\n<p><strong>Extraedge:</strong></p><p>The lesser omentum is extremely thin and is continuous with the two layers of peritoneum which cover respectively the antero-superior and postero-inferior surfaces of the stomach and first part of the duodenum. When these two layers reach the lesser curvature of the stomach and the upper border of the duodenum, they join and ascend as a double fold to the porta hepatis</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are derivatives of septum transversum, except:", "options": [{"label": "A", "text": "Falciform Ligament", "correct": false}, {"label": "B", "text": "Ligamentum teres", "correct": true}, {"label": "C", "text": "Coronary ligament", "correct": false}, {"label": "D", "text": "The mesentery of lesser sac", "correct": false}], "correct_answer": "B. Ligamentum teres", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ligamentum teres Ligamentum teres is a remnant of the left umbilical vein. The Ligamentum venosum is remnant of ductus venosus.</p>\n<p><strong>Highyeild:</strong></p><p>The septum transversum originally arises as the most cranial part of the mesenchyme on day 22 . During craniocaudal folding, it assumes a position of cranial to the developing heart at the level of the cervical vertebrae. During subsequent weeks the dorsal end of the embryo grows much faster than its ventral counterpart resulting in an apparent descent of the ventrally located septum transversum. At week 8, it can be found at the level of the thoracic vertebrae.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Falciform Ligament Option C. Coronary ligament Option D. Mesentery of lesser sac Mesentery of lesser sac (lesser omentum), falciform ligament, coronary ligament develop from septum transversum. Therefore Options A,C and D all are derivatives of septum transversum.</p>\n<p><strong>Extraedge:</strong></p><p>The cranial part of the septum transversum gives rise to the central tendon of the diaphragm and is the origin of the myoblasts that invade the pleuroperitoneal folds resulting in the formation of the muscular diaphragm. The caudal part of the septum transversum is invaded by the hepatic diverticulum, which divides within it to form the liver and thus gives rise to the ventral mesentery of the foregut, which in turn is the precursor of the lesser omentum, the visceral peritoneum of the liver and the falciform ligament.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Regarding pancreatic ducts, the false statement is:", "options": [{"label": "A", "text": "Main duct lies 2 cm distal and posterior to minor duct", "correct": false}, {"label": "B", "text": "Minor pancreatic duct opens in the duodenum at minor duodenal papilla", "correct": false}, {"label": "C", "text": "Major duct is made up of distal part of duct from dorsal bud and whole of ventral bud", "correct": false}, {"label": "D", "text": "Minor duct is made up of only the distal part of dorsal bud", "correct": true}], "correct_answer": "D. Minor duct is made up of only the distal part of dorsal bud", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Minor duct is made up of only the distal part of dorsal bud The accessory pancreatic duct is formed by proximal one-fourth of the duct of the dorsal pancreatic bud.</p>\n<p><strong>Highyeild:</strong></p><p>The pancreas develops from two endodermal pancreatic buds that arise from the junction of the foregut and midgut. The dorsal bud forms the upper part of the head, neck, body, and tail of the pancreas, while the ventral bud forms the lower part of the head and uncinate process. In the third month of fetal life, pancreatic islets (of Langerhans) develop from the parenchymatous pancreatic tissue and scatter throughout the pancreas.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Main duct lies 2 cm distal and posterior to minor duct Opening of the dorsal pancreatic duct is about 2 cm proximal to the opening of the ventral pancreatic duct. The ventral pancreatic duct opens in common with the bile duct derived from the hepatic bud. The proximal part of the dorsal pancreatic duct may persist as an accessory pancreatic duct ( duct of Santorini ) that opens in the duodenum at the minor duodenal papilla located about 2 cm proximal to the major duodenal papilla. Option B. Minor pancreatic duct opens in the duodenum at minor duodenal papilla The proximal part of the dorsal pancreatic duct may persist as an accessory pancreatic duct ( duct of Santorini ) that opens in the duodenum at minor duodenal papilla located about 2 cm proximal to the major duodenal papilla. Option C. Major duct is made up of the distal part of the duct from the dorsal bud and the whole of the ventral bud The main pancreatic duct (of Wirsung) is formed by the distal part of the dorsal pancreatic duct and the entire ventral pancreatic duct.</p>\n<p><strong>Extraedge:</strong></p><p>Development of Ducts of the Pancreas Initially two parts of the pancreas derived from two pancreatic buds have separate ducts called dorsal and ventral pancreatic ducts that open separately into the duodenum. The opening of the dorsal pancreatic duct is about 2 cm proximal to the opening of the ventral pancreatic duct. The ventral pancreatic duct opens in common with the bile duct derived from the hepatic bud. Now communication (anastomosis) develops between the dorsal and ventral pancreatic ducts. The main pancreatic duct ( duct of Wirsung ) develops from (a) dorsal pancreatic duct distal to anastomosis between the two ducts, (b) anastomosis (communication) between the two ducts, and (c) ventral pancreatic duct proximal to the anastomosis. From its development, it is clear that the main pancreatic duct that opens in the duodenum is common with the bile duct at the major duodenal papilla. The proximal part of the dorsal pancreatic duct may persist as an accessory pancreatic duct ( duct of Santorini ) that opens in the duodenum at the minor duodenal papilla located about 2 cm proximal to the major duodenal papilla. Schematic diagram to show the development of pancreatic ducts</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A newborn infant suffers from a posterolateral defect on the left side of the body. His abdominal contents have herniated through the defect into the thoracic cavity, and as a result, the infant suffers from pulmonary hypoplasia. His breathing difficulty is life-threatening because the herniation has inhibited lung development and inflation. This congenital defect is due to a malformation of which of the following?", "options": [{"label": "A", "text": "Mesentery of the esophagus", "correct": false}, {"label": "B", "text": "Muscular ingrowth of the body wall", "correct": false}, {"label": "C", "text": "Pleuropericardial membrane", "correct": false}, {"label": "D", "text": "Pleuroperitoneal membrane", "correct": true}], "correct_answer": "D. Pleuroperitoneal membrane", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pleuroperitoneal membrane The pleuroperitoneal membranes develop and close the pleuroperitoneal canals. They fuse with the dorsal mesentery of the esophagus and the septum transversum. The pleuroperitoneal membranes not only form a large portion of the early fetal diaphragm but also represent only a small portion of the diaphragm in the newborn. Congenital diaphragmatic hernia (CDH) : It is a herniation of abdominal contents into the pleural cavity through a large gap/ defect present in the posterolateral part of the diaphragm, most commonly on the left side. This defect (also called the foramen of Bochdalek) occurs due to defective development of the pleuroperitoneal membrane or failure of fusion of the pleuroperitoneal membrane with other elements of the diaphragm. When the abdominal contents like intestines, stomach, and/or spleen herniate in the thorax, they compress the developing lungs and cause hypoplasia. The diaphragmatic hernia is more common on the left side probably because the right pleuroperitoneal canal closes earlier than the left one.</p>\n<p><strong>Highyeild:</strong></p><p>Retrosternal hernia (parasternal hernia): Herethereisalargegap in sternocostal part of the diaphragm between the sternal and costal slips of the diaphragm (foramen of Morgagni) through which the intestines may herniate into the pericardial cavity or conversely a part of the heart may herniate into the epigastric region</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Mesentery of the esophagus The dorsal mesentery of the diaphragm is invaded by myoblasts and forms the crura of the diaphragm . Option B. Muscular ingrowth of the body wall On each side, the developing pleural cavity (pleuroperitoneal canal) burrows into the lateral body wall and splits it into two layers: external and internal. The external layer forms the definitive body wall. The internal layer forms the peripheral parts of the diaphragm external to the parts derived from the pleuroperitoneal membranes. Option C. Pleuropericardial membrane The pleuropericardial membranes participate in the formation of the mediastinum and do not contribute to the formation of the diaphragm.</p>\n<p><strong>Extraedge:</strong></p><p>Eventration of diaphragm : In this condition, musculature in one-half of the diaphragm remains thin and membranous, and hence balloons out in the thorax forming a diaphragmatic pouch because of upward displacement of abdominal viscera. This anomaly occurs when muscular tissue does not develop in the pleuroperitoneal membrane. It is more common on the left side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of these cells are found in the small intestine EXCEPT:", "options": [{"label": "A", "text": "Stem Cells", "correct": false}, {"label": "B", "text": "Goblet cells", "correct": false}, {"label": "C", "text": "Neck cells", "correct": true}, {"label": "D", "text": "Paneth cells", "correct": false}], "correct_answer": "C. Neck cells", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Neck cells Mucous neck cells are present in the stomach. These cells secrete mucinous secretion in the stomach.</p>\n<p><strong>Highyeild:</strong></p><p>Cells in Small Intestine Absorptive cells are the most common cells in the intestinal epithelium. These cells are tall and columnar with a prominent brush border of microvilli. A thick glycocalyx coat covers and protects the microvilli from the corrosive digestive chemicals. Goblet cells are interspersed among the columnar absorptive cells of the epithelium. They increase in number toward the distal region of the small intestine (ileum). Enteroendocrine or diffuse neuroendocrine system (DNES) cells are scattered throughout the epithelium of the villi and intestinal glands. Duodenal (Brunner) glands are primarily found in the submucosa of the initial portion of the duodenum and characterize this region of the small intestine. These are branched, tubuloacinar glands with light-staining mucous cells. The ducts of duodenal glands penetrate the muscularis mucosae and discharge their secretory products at the base of intestinal glands located between the villi. Undifferentiated or stem cells are located at the base of intestinal glands, and they exhibit increased mitotic activity. These stem cells replace all worn-out columnar absorptive cells, goblet cells, and intestinal gland cells in the small intestine. Paneth cells are located at the base of intestinal glands, characterized by deep-staining eosinophilic granules in their cytoplasm.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Stem Cells Undifferentiated or stem cells are located at the base of intestinal glands, and they exhibit increased mitotic activity. These stem cells replace all worn-out columnar absorptive cells, goblet cells, and intestinal gland cells in the small intestine. Option B. Goblet cells Goblet cells are interspersed among the columnar absorptive cells of the epithelium. They increase in number toward the distal region of the small intestine (ileum). Option D. Paneth cells Paneth cells are located at the base of intestinal glands, characterized by deep-staining eosinophilic granules in their cytoplasm.</p>\n<p><strong>Extraedge:</strong></p><p>The wall of the stomach is made of the same four layers as most of the rest of the alimentary canal, but with adaptations to the mucosa and muscularis for the unique functions of this organ. In addition to the typical circular and longitudinal smooth muscle layers, the muscularis has an inner oblique smooth muscle layer . As a result, in addition to moving food through the canal, the stomach can vigorously churn food, mechanically breaking it down into smaller particles.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True regarding the Paneth cells:", "options": [{"label": "A", "text": "Contain basophilic granules in cytoplasm", "correct": false}, {"label": "B", "text": "Located in stomach", "correct": false}, {"label": "C", "text": "Absent Lysozymes", "correct": false}, {"label": "D", "text": "Numerous Lysozymes", "correct": true}], "correct_answer": "D. Numerous Lysozymes", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Numerous Lysozymes Paneth cells (with pink eosinophilic granules in the cytoplasm) located in the bases of intestinal glands perform defensive functions in the digestive tract. So, paneth cells play an important role in the innate immunity of the gut. Paneth cells produce lysozyme, an antibacterial enzyme that digests the bacterial cell walls and membranes of microorganisms. These cells also release the hydrophobic peptide defensins in response to microbial presence. Thus, Paneth cells function in controlling the microbial flora in the small intestine and regulating the microenvironment of the intestinal crypts.</p>\n<p><strong>Highyeild:</strong></p><p>Paneth cells are found throughout the small intestine and the appendix at the base of the intestinal glands. The Paneth cell increases in number towards the end of the small intestine.Like the other epithelial cell lineages in the small intestine, Paneth cells originate at the stem cell region near the bottom of the gland. There are, on average, 5–12 Paneth cells in each small intestinal crypt.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Contain basophilic granules in cytoplasm Paneth cells are cells in the small intestine epithelium, alongside goblet cells, enterocytes, and enteroendocrine cells, also found in the cecum and appendix. They are below the intestinal stem cells in the intestinal glands (also called crypts of Lieberkühn) and the large eosinophilic refractile granules that occupy most of their cytoplasm. Option B. Located in stomach Paneth cells are located at the base of intestinal glands, characterized by deep-staining eosinophilic granules in their cytoplasm. Option C. Absent Lysozymes Paneth cells produce lysozyme , an antibacterial enzyme that digests the bacterial cell walls and membranes of microorganisms. These cells also release the hydrophobic peptide defensins in response to microbial presence.</p>\n<p><strong>Extraedge:</strong></p><p>Unlike the other epithelial cell types, Paneth cells migrate downward from the stem cell region and settle just adjacent to it. This close relationship to the stem cell region suggests that Paneth cells are important in defending the gland stem cells from microbial damage.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Oxyntic cells are present in which part of the stomach:", "options": [{"label": "A", "text": "Pylorus", "correct": false}, {"label": "B", "text": "Cardiac notch", "correct": false}, {"label": "C", "text": "Body", "correct": true}, {"label": "D", "text": "Base", "correct": false}], "correct_answer": "C. Body", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Body Oxyntic cells/parietal cells They are large, ovoid or polyhedral, with a large central nucleus. They are present singly, sandwiched between peptic cells and basement membrane. They are more numerous in the upper half of the body of the gastric glands than in its lower half. They are called oxyntic cells because they stain strongly with eosin. They are called parietal cells as they lie against the basement membrane and often bulge outward (into the lamina propria), creating a beaded appearance.</p>\n<p><strong>Highyeild:</strong></p><p>Oxyntic cells secrete hydrochloric acid. HCl helps in the conversion of inactive enzymes to their active forms.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Pylorus The glands of the cardia and pylorus are composed primarily of mucus-secreting cells. Cells that make up the pyloric antrum secrete mucus and a number of hormones, including the majority of the stimulatory hormone, gastrin . Option B. Cardiac notch The glands of the cardia and pylorus are composed primarily of mucus-secreting cells. Cells that make up the pyloric antrum secrete mucus and a number of hormones, including the majority of the stimulatory hormone, gastrin . Option D. Base of Gland At the base of the gland is the zymogenic (chief) cells. Located primarily in the basal regions of gastric glands are chief cells , which secrete pepsinogen , the inactive proenzyme form of pepsin. HCl is necessary for the conversion of pepsinogen to pepsin.</p>\n<p><strong>Extraedge:</strong></p><p>They also produce an intrinsic factor of Castle (a glycoprotein) that combines with vitamin B 12 (present in the ingested food and constituting an extrinsic factor) to form a complex necessary for normal formation of erythrocytes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Kupffer cells are seen in the sinusoids of which of the following organs?", "options": [{"label": "A", "text": "Spleen", "correct": false}, {"label": "B", "text": "Bone marrow", "correct": false}, {"label": "C", "text": "Liver", "correct": true}, {"label": "D", "text": "Adrenal", "correct": false}], "correct_answer": "C. Liver", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Liver Kupffer cell cells are modified macrophages present in the liver. The sinusoids are lined with discontinuous endothelial cells. The narrow separations between the endothelial cells and hepatocytes show the space of Disse . Located between the hepatocytes are tiny channels that, in the cross-section appear as dots; these are the bile canaliculi. Also visible in the sinusoids are the larger phagocytic Kupffer cells that can span the sinusoid. Kupffer cells are large cells with several processes and an irregular or stellate outline that protrudes into the sinusoids of the liver.</p>\n<p><strong>Highyeild:</strong></p><p>The perisinusoidal space (or space of Disse) is a location in the liver between a hepatocyte and a sinusoid. It contains blood plasma. Microvilli of hepatocytes extend into this space, allowing proteins and other plasma components from the sinusoids to be absorbed by the hepatocytes. Space of Disse</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A, B & D does not contain kupffer cells. Kupffer cells are phagocytic cell which forms the lining of the sinusoids of the liver and is involved in the breakdown of red blood cells.</p>\n<p><strong>Extraedge:</strong></p><p>The perisinusoidal space also contains hepatic stellate cells (also known as Ito cells), which store fat or fat soluble vitamins including vitamin A). A variety of insults that cause inflammation can result in the cells transforming into myofibroblasts, resulting in collagen production, fibrosis, and cirrhosis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following are the components of the white pulp of the spleen except:", "options": [{"label": "A", "text": "Periarteriolar Lymphoid Sheath", "correct": false}, {"label": "B", "text": "B Cells", "correct": false}, {"label": "C", "text": "Antigen Presenting Cells", "correct": false}, {"label": "D", "text": "Vascular Sinus", "correct": true}], "correct_answer": "D. Vascular Sinus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Vascular Sinus Functional correlations: Spleen The spleen is the largest lymphoid organ with an extensive blood supply. It filters blood and is the site of immune responses to blood-borne antigens. The two major components of the spleen are the red pulp and the white pulp. Vascular sinus is a component of the red pulp of the spleen.</p>\n<p><strong>Highyeild:</strong></p><p>White pulp is the immune component of the spleen and consists of accumulated lymphocytes in the lymphatic nodules that surround the central artery or arteriole. Lymphocytes around the central arteries of the white pulp form the periarteriolar lymphatic sheaths (PALS) and contain primarily T cells, macrophages, and antigen presenting cells (APCs). The lymphatic nodules contain mainly B cells. The cells in the spleen detect trapped bacteria and antigens and initiate immune responses against them. As a result, T cells and B cells interact, become activated, proliferate, and perform their immune response.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Periarteriolar Lymphoid Sheath Option B. B cells Option C. Antigen presenting cells Option A, B & C all are content of white pulp of the spleen.</p>\n<p><strong>Extraedge:</strong></p><p>Red pulp consists of a dense network of reticular fibres that contains erythrocytes, lymphocytes, plasma cells, macrophages, and other granulocytes. The main function of the red pulp is to filter the blood. It removes antigens, microorganisms, platelets, and aged or abnormal erythrocytes from the blood.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 17-year-old student is brought to the emergency room, displaying vomiting, fever, and diarrhea. The patient reports that for a period of 24 hours prior to admission, he suffered from abdominal pain first centred around the navel and then moving inferiorly to the right. As the patient talks, you realize that he is gesturing toward McBurney’s point. You tentatively diagnose acute appendicitis and request emergency surgery. Accurate visual identification of the appendix during surgery can be verified by using which of the following landmarks?", "options": [{"label": "A", "text": "Bifurcation of the abdominal aorta", "correct": false}, {"label": "B", "text": "Epiploic appendages", "correct": false}, {"label": "C", "text": "Haustra", "correct": false}, {"label": "D", "text": "Taeniae coli", "correct": true}], "correct_answer": "D. Taeniae coli", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Taeniae coli The position of the appendix varies depending on the patient. The taeniae coli are three longitudinal bands of smooth muscle running the length of the colon. Since the appendix is part of the colon, the taeniae coli can be accurately followed to this structure. Taeniae coli or longitudinal band of muscles, terminate at the appendix.</p>\n<p><strong>Highyeild:</strong></p><p>The taeniae coli converge at the base of the appendix in the cecum where they form a complete longitudinal layer. In the ascending and descending colon, the bands are located anteriorly, posteromedially and posterolaterally.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The bifurcation of the abdominal aorta and inferior border of the right kidney is retroperitoneal and would not be of value in the identification of the appendix. Option: B. The epiploic appendages are small pockets of fatty tissue along the length of the colon, but they are not found in the appendix. Option: C. The haustra are sacculations of the large intestine resulting from contractions of the taeniae coli.</p>\n<p><strong>Extraedge:</strong></p><p>In the sigmoid colon, the taeniae coli gradually broaden to form anterior and posterior layers, which fuse laterally, to form the longitudinal layer of the rectum. Clinical importance In an appendectomy, if the appendix is not immediately obvious, the taeniae coli can be used as a guide to identify the appendix where they merge at its base.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 2-day-old female infant with a fever is examined by the pediatric team. Imaging reveals malrotation of the small intestine without fixation of the mesenteries. The vessels around the duodenojejunal junction are obstructed, and the intestine is at risk of becoming gangrenous. Which of the following has occurred to cause the obstruction?", "options": [{"label": "A", "text": "Diaphragmatic Atresia", "correct": false}, {"label": "B", "text": "Congenital megacolon", "correct": false}, {"label": "C", "text": "Midgut volvulus", "correct": true}, {"label": "D", "text": "Duplication of the intestine", "correct": false}], "correct_answer": "C. Midgut volvulus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Midgut volvulus Midgut volvulus is a possible complication of malrotation of the midgut loop without fixed mesentery . The small intestines twist around the vasculature that provides support for them. This can result in ischemic necrosis of the intestine. Midgut volvulus can be responsible for the malabsorption of food and diarrhea.</p>\n<p><strong>Highyeild:</strong></p><p>Midgut volvulus is a complication of bowel malrotation usually seen in neonates and infants. Presentation is usually with proximal small bowel obstruction and bilious vomiting. Without prompt treatment, there is a real and significant risk of small bowel ischaemia, significant associated morbidity and even death.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Diaphragmatic Atresia Diaphragmatic atresia is not a cause of volvulus. Subhepatic cecum is due to failure of the descent of the cecal bud and results in the absence of an ascending colon. Option B. Congenital megacolon Congenital megacolon is due to faulty migration of neural crest cells into the wall of the colon, which causes a lack of parasympathetic postganglionic neurons. Option D. Duplication of the intestine Duplication of the intestine would not cause volvulus because there would still be a fixed mesentery and no free movement of the intestines.</p>\n<p><strong>Extraedge:</strong></p><p>Typically, the neonate of midgut volvulus is entirely normal for a period and then suddenly presents with bilious vomiting. Unless the volvulus is reduced (or reduces spontaneously), the superior mesenteric vein wrapped around the superior mesenteric artery causes progressive venous obstruction, gradual onset of ischaemia, and eventual necrosis. As this occurs, the abdomen becomes swollen and tender as fluid accumulates in the lumen of the bowel. Eventually, in severe, untreated cases, peritonitis and shock can result in severe morbidity and, sometimes, mortality.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 30 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Primitive ectoderm develops from", "options": [{"label": "A", "text": "Epiblast", "correct": true}, {"label": "B", "text": "Hypoblast", "correct": false}, {"label": "C", "text": "Primordial germ cells", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Epiblast", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Epiblast Primitive ectoderm develops from Epiblast. Formation of hypoblast : Some cells of the inner cell mass differentiate into flattened cells that come to line its free surface (Image A). This layer is the hypoblast/endoderm. Formation of epiblast : The remaining cells of the inner cell mass become columnar (Image B). These cells form the epiblast/ectoderm. The embryo is now in the form of a disc having two layers ( Bilaminar germ disc). Formation of amniotic cavity : A space appears between the epiblast (below) and the trophoblast (above). This is the amniotic cavity (Image C), filled by amniotic fluid, or liquor amnii. The roof of this cavity is formed by amniogenic cells derived from the trophoblast, while its floor is formed by the epiblast. Formation of primary yolk sac : Flattened cells arising from the hypoblast, spread and line the inside of the blastocystic cavity. (This lining of flattened cells is called “Heuser’s membrane” ). In this way, a cavity, lined on all sides by cells of endodermal origin, is formed. This cavity is called the primary yolk sac. (Image D).</p>\n<p><strong>Highyeild:</strong></p><p>Differentiation of endoderm and ectoderm, and the formation of the amniotic cavity and the yolk sac</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option D. None of the above Primitive ectoderm develops from Epiblast Hence d ) none of the above is incorrect. Option B. Hypoblast Primitive endoderm develops from b) hypoblast. Option C . Primordial germ cells primordial germ cells form gonads.</p>\n<p><strong>Extraedge:</strong></p><p>Formation of extraembryonic mesoderm: The cells of the trophoblast give origin to a mass of cells called the extraembryonic mesoderm (or primary mesoderm). These cells come to lie between the trophoblast and the flattened endodermal cells lining the yolk sac, thus separating them from each other. These cells also separate the wall of the amniotic cavity from the trophoblast. This mesoderm is called “extra-embryonic” because it lies outside the embryonic disc. It does not give rise to any tissues of the embryo.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Primordial germ cells are formed at:", "options": [{"label": "A", "text": "2nd week of embryogenesis", "correct": true}, {"label": "B", "text": "5th week of embryogenesis", "correct": false}, {"label": "C", "text": "3rd week of embryogenesis", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. 2nd week of embryogenesis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2nd week of embryogenesis Primordial germ cells are formed in 2nd week of embryogenesis.</p>\n<p><strong>Highyeild:</strong></p><p>Gametes are derived from primordial germ cells (PGCs) that are formed in the epiblast during the second week, move through the primitive streak during gastrulation, and migrate to the wall of the yolk sac. During the fourth week, these cells begin to migrate from the yolk sac toward the developing gonads, where they arrive by the end of the fifth week. An embryo at the end of the third week, showing the position of primordial germ cells [PGCs] in the wall of the yolk sac, close to the attachment of the future umbilical cord.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. 5th week of embryogenesis Primordial germ cells migrate in the 5th week of embryogenesis from the yolk sac to the genital ridge to help in the formation of gonads. Option C. 3rd week of embryogenesis The 3rd week of embryogenesis is considered a week of gastrulation where all three germ layers are formed. Option D. None of the above Primordial germ cells are formed in 2nd week of embryogenesis. Hence d) none of the above is incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>Teratomas are tumours that arise from pluripotent stem cells that can differentiate into any of the three germ layers or their derivatives. Some evidence suggests that PGCs that have strayed from their normal migratory paths could be responsible for some of these tumou Another source may be epiblast cells that give rise to all three germ layers during gastrulation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Oogenesis starts at", "options": [{"label": "A", "text": "Before Birth", "correct": true}, {"label": "B", "text": "At birth", "correct": false}, {"label": "C", "text": "At puberty", "correct": false}, {"label": "D", "text": "After puberty", "correct": false}], "correct_answer": "A. Before Birth", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Before Birth Oogenesis starts before birth and ovaries become inactive during childhood, which again Later, ovaries get activated at puberty and function till menopause.</p>\n<p><strong>Highyeild:</strong></p><p>Oogenesis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B . At birth Option C. At puberty Option D. After puberty Oogenesis starts before birth and ovaries become inactive during childhood, which again Later, ovaries get activated at puberty and function till menopause. Hence the options b) at birth, c) at puberty and d) after puberty are all incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>The primary oocyte enters into the first meiotic division before birth and completes it at puberty just before ovulation. Primary oocytes are not formed after birth. The secondary oocyte, at the time of ovulation, is in the metaphase stage of the second meiotic division, which continues till fertilization. The secondary oocyte completes its meiotic division only when it is fertilized. At birth, the ovary contains about two million germ cells. Thereafter most of them degenerate and, by puberty, when ovulation begins only about 40,000 oocytes are left in the ovary.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The total number of oocytes ovulated in reproductive life:", "options": [{"label": "A", "text": "400", "correct": true}, {"label": "B", "text": "40000", "correct": false}, {"label": "C", "text": "400000", "correct": false}, {"label": "D", "text": "none of the above", "correct": false}], "correct_answer": "A. 400", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>400 The total number of oocytes ovulated in reproductive life is 400.</p>\n<p><strong>Highyeild:</strong></p><p>Near the time of birth, all primary oocytes have started prophase of meiosis I, but instead of proceeding into metaphase, they enter the diplotene stage, a resting stage during prophase that is characterized by a lacy network of chromatin. Primary oocytes remain arrested in prophase and do not finish their first meiotic division before puberty is reached. This arrested state is produced by oocyte maturation inhibitor (OMI) , a small peptide secreted by follicular cells.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. 40000 Total number of oocytes functional at puberty 40,000 Option C. 400000 The total number of oocytes functional at birth is 4,00,000. Option D. None of the above The total number of oocytes ovulated in reproductive life is 400. Hence d) none of the above is incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>The total number of primary oocytes at birth is estimated to vary from 600,000 to 800,000. During childhood, most oocytes become atretic; only approximately 40,000 are present by the beginning of puberty, and fewer than 500 will be ovulated.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the correct sequence:", "options": [{"label": "A", "text": "Oogonium – primary oocyte – secondary oocyte plus first polar body", "correct": true}, {"label": "B", "text": "Oogonium – primary oocyte – secondary oocyte plus second polar body", "correct": false}, {"label": "C", "text": "Oogonium – secondary oocyte – primary oocyte plus first polar body", "correct": false}, {"label": "D", "text": "Oogonium – primary oocyte plus first polar body -secondary oocyte", "correct": false}], "correct_answer": "A. Oogonium – primary oocyte – secondary oocyte plus first polar body", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Oogonium – primary oocyte – secondary oocyte plus first polar body The correct sequence of Oogenesis is Oogonium- primary oocyte- secondary oocyte plus first polar body.</p>\n<p><strong>Highyeild:</strong></p><p>Stages in oogenesis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. oogonium – primary oocyte – secondary oocyte plus second polar body, Option C. oogonium – secondary oocyte – primary oocyte plus first polar body and, Option D. oogonium – primary oocyte plus first polar body -secondary oocyte, The correct sequence of Oogenesis is Oogonium- primary oocyte- secondary oocyte plus first polar body incorrect.,</p>\n<p><strong>Extraedge:</strong></p><p>Ovulation takes place while the oocyte is in metaphase. The secondary oocyte remains arrested in metaphase till fertilization occurs. The second meiotic division is completed only if fertilization occurs. This division results in two unequal daughter cells. The larger cell is called the The smaller daughter cell is called the second polar body. The first polar body may also divide during the second meiotic division making a total of three polar bodies.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the correct sequence of spermatogenesis:", "options": [{"label": "A", "text": "Spermatogonia -spermatid - spermatozoa", "correct": true}, {"label": "B", "text": "Spermatogonia- spermatozoa- spermatid", "correct": false}, {"label": "C", "text": "Spermatid -spermatogonia- spermatozoa", "correct": false}, {"label": "D", "text": "Spermatozoa- spermatogonia – spermatid", "correct": false}], "correct_answer": "A. Spermatogonia -spermatid - spermatozoa", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spermatogonia -spermatid - spermatozoa The correct sequence of spermatogenesis : Spermatogonia – primary spermatocyte- secondary spermatocyte- spermatid- spermatozoa.</p>\n<p><strong>Highyeild:</strong></p><p>Stages in spermatogenesis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. spermatogonia- spermatozoa- spermatid, Option C. spermatid -spermatogonia- spermatozoa and Option D. spermatozoa- spermatogonia – spermatid The correct sequence of spermatogenesis : Spermatogonia – primary spermatocyte- secondary spermatocyte- spermatid- spermatozoa, Hence B, C and D options are all incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>Parts of a spermatozoon and their derivation</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which stage is considered as a stage of independent assortment of maternal and paternal chromosomes:", "options": [{"label": "A", "text": "Meiosis I", "correct": true}, {"label": "B", "text": "Meiosis II", "correct": false}, {"label": "C", "text": "Mitosis I", "correct": false}, {"label": "D", "text": "Both a & b", "correct": false}], "correct_answer": "A. Meiosis I", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Meiosis I Meiosis I is considered a stage of independent assortment of maternal and paternal chromosomes. During meiosis I diploid number of primary spermatocytes is converted into haploid secondary spermatocytes.</p>\n<p><strong>Highyeild:</strong></p><p>Spermatogenesis Definition: It is the process of maturation of male gametes in the wall of seminiferous tubules. It involves a series of changes leading to the conversion of spermatogonia into spermatozoa. Time: In the male, the formation of gametes (spermatozoa) takes place only during the reproductive period, which begins at the age of puberty (12–16 years) and continues even into old age. Duration: 64–74 days.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Meiosis II Meiosis II converts secondary spermatocyte into spermatid. Option C. Mitosis I Mitosis I converts spermatogonia into primary spermatocytes. Option D . Both a & b Option b) Meiosis II converts secondary spermatocyte into spermatid whereas Option c) Mitosis I converts spermatogonia into primary spermatocyte, Hence d) both a & b is incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>Differences between spermatogenesis and oogenesis Spermatogenesis Oogenesis Continuous process from puberty to death Cyclical from puberty to menopause Absent before puberty Starts before puberty-intrauterine life Number of gametes released are 200-300 million/ejaculation 400-500 mature ova are released during reproductive life Meiosis I results in two secondary spermatocytes from one primary spermatocyte Meiosis I results in one secondary oocyte from one primary oocyte Meiosis Il results in four spermatids from one primary spermatocyte Meiosis II results in one ovum from one primary oocyte Relatively short diplotene stage Prolonged diplotene stage Four gametes are of equal size One large gamete (Ovum) and 2/3 polar bodies Participates in fertilization only after completion of meiosis Participates in fertilization before completion of meiosis When the primary spermatocyte divides, its cytoplasm is equally distributed between the two secondary spermatocytes formed ● When the primary oocyte divides, almost all its cytoplasm goes to the daughter cell, which forms the secondary oocyte.● The other daughter cell (first polar body) receives half the chromosomes of the primary oocyte, but almost no cytoplasm. Most cytoplasm is shed from spermatozoon Cytoplasm is conserved in the ovum</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are true about spermatogenesis except:", "options": [{"label": "A", "text": "Process by which spermatogonia forms mature spermatozoa", "correct": false}, {"label": "B", "text": "Takes about 72-74 days", "correct": false}, {"label": "C", "text": "One spermatogonia can produce 64-512 spermatids", "correct": false}, {"label": "D", "text": "Conversion of secondary spermatocyte to spermatozoa is known as spermatogenesis", "correct": true}], "correct_answer": "D. Conversion of secondary spermatocyte to spermatozoa is known as spermatogenesis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Conversion of secondary spermatocyte to spermatozoa is known as spermatogenesis Spermatogenesis Spermatogenesis is the process of maturation of male gametes in the wall of seminiferous tubules, It involves a series of changes leading to the conversion of spermatogonia into spermatozoa.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Process by which spermatogonia forms mature spermatozoa Spermatogenesis is the process of maturation of male gametes in the wall of seminiferous tubules, It involves a series of changes leading to the conversion of spermatogonia into spermatozoa. Option B. Takes about 72-74 days The duration of Spermatogenesis is from 64 to 74 days. Option C. One spermatogonia can produce 64-512 spermatids. Each type of spermatogonium undergoes 5 meiotic divisions to produce 32 type B spermatogonia, which in turn produces 64 primary spermatocytes that then lead to the formation of 512 spermatids from one spermatogonium.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about Spermiation:", "options": [{"label": "A", "text": "Conversion of spermatogonia into spermatozoa", "correct": false}, {"label": "B", "text": "Conversion of spermatid into spermatozoa", "correct": false}, {"label": "C", "text": "Process by which spermatozoa are released into the lumen of seminiferous tubule", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. Process by which spermatozoa are released into the lumen of seminiferous tubule", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Process by which spermatozoa are released into the lumen of seminiferous tubule Spermiation is the process by which mature spermatids are released from the supporting somatic Sertoli cells into the lumen of the seminiferous tubule. It is a critical determinant of the number of sperm entering the epididymis, and thus the sperm content of the ejaculate.</p>\n<p><strong>Highyeild:</strong></p><p>The process by which the spermatids are transformed into mature spermatozoa is known as spermiogenesis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Conversion of spermatogonia into spermatozoa Spermiation is a process by which spermatozoa is released into the lumen of the seminiferous tubule. Option B. Conversion of spermatid into spermatozoa Spermiation is a process by which spermatozoa is released into the lumen of the seminiferous tubule. Option D . None of the above Spermiation is a process by which spermatozoa is released into the lumen of the seminiferous tubule, Hence d) none of the above is incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>The axial filament is responsible for the movements of the spermatozoon, while mitochondria supply energy for these movements.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Site of spermatogenesis:", "options": [{"label": "A", "text": "Epididymis", "correct": false}, {"label": "B", "text": "Fallopian tube", "correct": false}, {"label": "C", "text": "Seminiferous tubule", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. Seminiferous tubule", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Seminiferous tubule The seminiferous tubule is the site for spermatogenesis.</p>\n<p><strong>Highyeild:</strong></p><p>S permatogenesis is the process of the formation of s permatozoa from primordial germ cells (PGCs)/spermatogonia present in the walls of the seminiferous tubules of the testis. The PGCs remain dormant in the seminiferous tubules of the testes till puberty. At puberty, they undergo a series of divisions to form spermatogonia.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Epididymis Epididymis is the storage site for sperms, the site of maturation and provides motility to sperms. Option B. Fallopian tube The fallopian tube is the site where the capacitation of sperm occurs Option D. None of the above The seminiferous tubule is the site for spermatogenesis, Hence d) none of the above is incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>The PGCs divide by mitosis to form dark type A spermatogonia, which act as stem cells. Each dark type A Spermatogonium undergoes mitosis to form one dark A spermatogonium and another light type A spermatogonium. The dark type A spermatogonia are kept in reserve for repetition of the next cycle. The light type A undergoes mitotic division to form two dark type B spermatogonia. The type B Spermatogonium undergoes mitotic division to form two primary spermatocytes (largest germ cells).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are functions of the marked structure except", "options": [{"label": "A", "text": "Site of storage", "correct": false}, {"label": "B", "text": "Maturation", "correct": false}, {"label": "C", "text": "Provides motility", "correct": false}, {"label": "D", "text": "Spermiation", "correct": true}], "correct_answer": "D. Spermiation", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681192072-QTDA013011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spermiation The marked structure in the image is the Spermiation is a process by which spermatozoa are released into the lumen of the seminiferous tubule. It takes place in seminiferous tubules of the</p>\n<p><strong>Highyeild:</strong></p><p>The epididymis lies posterior and slightly lateral to the testis. Anatomically, it is divided into three sections: head, body and tail. Between 8 and 12 efferent ductules from the superior pole of the testis drain into and form the head of the epididymis. Distally, the tail of the epididymis becomes continuous with the convoluted portion of the ductus deferens. The epididymis is invested by the tunica vaginalis, continuous with that covering the testis. Laterally, a deep groove, the sinus of the epididymis, marks the boundary between the testis and epididymis. Epididymis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Site of storage Option B. Maturation Option C. Provides motility Options -a) site of storage, b) maturation and c) provides motility to sperms are true statements about epididymis.</p>\n<p><strong>Extraedge:</strong></p><p>The descent of the testes from the abdominal cavity to the scrotum can be arrested at any point along the pathway of the testis, e.g. the deep inguinal ring, in the inguinal canal, or between the superficial inguinal ring and the scrotum. Retention in the inguinal canal is associated with a patent processus vaginalis and can be further complicated by a congenital hernia. Occasionally, the testis migrates outside its normal path of descent and lies in an ectopic location. At birth, 3% of full-term male infants have unilaterally undescended testis. By six months of age, this number decreases to less than 1%. Undescended testes are associated with a higher risk of infertility and testicular cancer later in life.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In oogenesis, Meiosis I stage gets arrested at which of the following stage:", "options": [{"label": "A", "text": "Metaphase", "correct": false}, {"label": "B", "text": "prophase", "correct": true}, {"label": "C", "text": "both a & b", "correct": false}, {"label": "D", "text": "none of the above", "correct": false}], "correct_answer": "B. prophase", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>prophase In oogenesis, Meiosis I stage gets arrested at the prophase stage, in the diplotene phase. Near the time of birth, all primary oocytes have started the prophase of meiosis I, but instead of proceeding into metaphase, they enter the diplotene stage, a resting stage during prophase that is characterized by a lacy network of chromatin.</p>\n<p><strong>Highyeild:</strong></p><p>Primary oocytes remain arrested in prophase and do not finish their first meiotic division before puberty is reached. This arrested state is produced by oocyte maturation inhibitor (OMI), a small peptide secreted by follicular cells. The total number of primary oocytes at birth is estimated to vary from 600,000 to 800,000. During childhood, most oocytes become atretic; only approximately 40,000 are present by the beginning of puberty, and fewer than 500 will be ovulated.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Metaphase Option C. both a & b Option D. none of the above In oogenesis, the Meiosis II stage gets arrested at a)metaphase stage, Hence c) both a & b and d) none of the above is</p>\n<p><strong>Extraedge:</strong></p><p>Spermiogenesis The series of changes resulting in the transformation of spermatids into spermatozoa is These changes include (1) formation of the acrosome, which covers half of the nuclear surface and contains enzymes to assist in penetration of the egg and its surrounding layers during fertilization; (2) condensation of the nucleus; (3) formation of the neck, middle piece, and tail; and (4) shedding of most of the cytoplasm as residual bodies that are phagocytized by Sertoli cells. In humans, the time required for a spermatogonium to develop into a mature spermatozoon is approximately 74 days, and approximately 300 million sperm cells are produced daily.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Polar bodies are formed during:", "options": [{"label": "A", "text": "Spermatogenesis", "correct": false}, {"label": "B", "text": "Organogenesis", "correct": false}, {"label": "C", "text": "Oogenesis", "correct": true}, {"label": "D", "text": "Morphogenesis", "correct": false}], "correct_answer": "C. Oogenesis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Oogenesis Polar bodies are formed during oogenesis. A polar body is a small haploid cell that is formed concomitantly during oogenesis but generally cannot be fertilized. When certain diploid cells in animals undergo cytokinesis after meiosis to produce egg cells, they sometimes divide unevenly.</p>\n<p><strong>Highyeild:</strong></p><p>The process by which a spermatid (22+X/22+Y) gradually changes its shape to become a spermatozoon is called spermiogenesis (or Spermateleosis). It is the final stage in the maturation of spermatids into mature, motile spermatozoa.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Spermatogenesis Spermatogenesis is the production of sperm from the primordial germ cells. Polar bodies are not formed during spermatogenesis. Option B. Organogenesis Organogenesis is the process of the formation of organs from three germ layers. It concerns cell-cell interaction, cell fate determination, cell proliferation and survival, cell and tissue shape and size, and arrangement of cells into tissues and ultimately functional organs. Polar bodies are not formed during organogenesis. Option D. Morphogenesis Morphogenesis is the biological process that causes a cell, tissue or organism to develop its shape. It is one of three fundamental aspects of developmental biology along with the control of tissue growth and patterning of cellular differentiation. Polar bodies are not formed during Morphogenesis.</p>\n<p><strong>Extraedge:</strong></p><p>Different events in gametogenesis The process of gametogenesis includes Formation and migration of PGC and their differentiation into male or female sex cells Mitotic divisions of germ cells Meiotic reduction in DNA or chromosome content of the germ cells Differentiation and maturation of germ cells. Phase 1 and 2 are similar in both sexes whereas the timing and pattern of phases 3 and 4 differ.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Independent assortment of chromosomes occurs at which level:", "options": [{"label": "A", "text": "Primordial germ cell to spermatogonia", "correct": false}, {"label": "B", "text": "Spermatogonia to primary spermatocyte", "correct": false}, {"label": "C", "text": "Primary spermatocyte to secondary spermatocyte", "correct": true}, {"label": "D", "text": "Secondary spermatocyte to spermatids", "correct": false}], "correct_answer": "C. Primary spermatocyte to secondary spermatocyte", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Primary spermatocyte to secondary spermatocyte Anaphase I of meiosis begins with the release of cohesion between the arms of sister chromatids, much as it does during mitosis. As the positioning of bivalent pairs is random, the assortment of maternal and paternal chromosomes in each telophase nucleus is also random. So, all this happens in meiosis 1. And, in spermatogenesis - meiosis 1 occurs when primary spermatocytes change to secondary spermatocytes.</p>\n<p><strong>Highyeild:</strong></p><p>Spermatogenesis (Simplified form)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Primordial germ cell to spermatogonia An independent assortment of chromosomes occurs in Meiosis 1, and in spermatogenesis - meiosis 1 occurs when primary spermatocytes change to secondary spermatocytes. Option B. Spermatogonia to primary spermatocyte An independent assortment of chromosomes occurs in Meiosis 1, and in spermatogenesis - meiosis 1 occurs when primary spermatocytes change to secondary spermatocytes. Option D. Secondary spermatocyte to spermatids An independent assortment of chromosomes occurs in Meiosis 1, and in spermatogenesis - meiosis 1 occurs when primary spermatocytes change to secondary spermatocytes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "After entering the first meiotic division, the primary oocyte remains arrested in which stage:", "options": [{"label": "A", "text": "Metaphase", "correct": false}, {"label": "B", "text": "Anaphase", "correct": false}, {"label": "C", "text": "Diplotene", "correct": true}, {"label": "D", "text": "Pachytene", "correct": false}], "correct_answer": "C. Diplotene", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Diplotene The primary oocytes become arrested in the diplotene stage of prophase I (the prophase of the first meiotic division). Shortly before birth, all the fetal oocytes in the female ovary have attained this stage.</p>\n<p><strong>Highyeild:</strong></p><p>The PGCs divide by mitosis to form a large number of oogonia. Each oogonium then enlarges to form a primary oocyte . The primary oocyte enters the prophase of the first meiotic division before birth. But this division is arrested till puberty due to the presence of an oocyte maturation inhibitor ( OMI ) factor secreted by the follicular cells surrounding the oocyte. The first meiotic division gets completed only when primary oocytes start maturing and are getting prepared for ovulation.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A . Metaphase Option B. Anaphase and Option D. Pachytene all are incorrect answers because the primary oocytes become arrested in the diplotene stage of prophase I (the prophase of the first meiotic division).</p>\n<p><strong>Extraedge:</strong></p><p>The secondary oocyte enters the second meiotic division at the time of ovulation, but this division is completed only after the sperm has penetrated the secondary oocyte. The second meiotic division is also unequal so that one daughter cell receives most of the cytoplasm and forms the ovum, while the other daughter cell receives a very small amount of cytoplasm and forms the second polar body.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about spermatid:", "options": [{"label": "A", "text": "Derived from primary spermatocyte", "correct": false}, {"label": "B", "text": "Derived from secondary spermatocyte", "correct": true}, {"label": "C", "text": "Undergoes mitotic division", "correct": false}, {"label": "D", "text": "Undergoes meiotic division", "correct": false}], "correct_answer": "B. Derived from secondary spermatocyte", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Derived from secondary spermatocyte Spermatids are derived from secondary spermatocytes. A spermatid is the male animal cell type that results from the completion of the second division associated with meiosis. The only location where meiosis occurs in males is within the testis and the cell type from which spermatids form are secondary spermatocytes.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Derived from primary spermatocyte, Option C. Undergoes mitotic division, Option D. Undergoes meiotic division, all are incorrect answers because a spermatid is the male animal cell type that results from the completion of the second division associated with meiosis. The only location where meiosis occurs in males is within the testis and the cell type from which spermatids form are secondary spermatocytes.</p>\n<p><strong>Extraedge:</strong></p><p>The head of the sperm appears somewhat like a spearhead in the It mainly consists of a nucleus that contains the condensed chromatin material (mostly DNA). Anterior two-thirds of the nucleus is covered by an acrosomal cap that contains various enzymes including hyaluronidase and acrosin.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Fertilization is complete when:", "options": [{"label": "A", "text": "1st Polar body is formed", "correct": false}, {"label": "B", "text": "2nd polar body is formed", "correct": true}, {"label": "C", "text": "Primary oocyte is formed", "correct": false}, {"label": "D", "text": "Secondary oocyte is formed", "correct": false}], "correct_answer": "B. 2nd polar body is formed", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2nd polar body is formed The 2nd Polar body is formed only as a result of fertilization. In meiosis 1, a diploid cell becomes 2 haploid (23 chromosomes) daughter cells, each chromosome has two chromatids. One cell becomes the secondary oocyte the other cell forms the first polar body. At fertilization, meiosis 2 is completed, forming a second polar body.</p>\n<p><strong>Highyeild:</strong></p><p>The secondary oocyte receives most of the cytoplasm; the other, the first polar body, receives practically none. The first polar body lies between the zona pellucida and the cell membrane of the secondary oocyte in the perivitelline space. The cell then enters meiosis II but arrests in metaphase approximately 3 hours before ovulation. Meiosis II is completed only if the oocyte is fertilized; otherwise, the cell degenerates approximately 24 hours after ovulation. The first polar body may undergo a second division.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. 1st Polar body is formed The first meiotic division is unequal; most of the cytoplasm goes to one daughter cell forming a secondary oocyte , while the other daughter cell receives minimal cytoplasm and forms the first polar body . Option C. Primary oocyte is formed All primary oocytes are formed by the fifth month of fetal life and remain dormant in the prophase of meiosis I until puberty. During a woman's ovarian cycle, one oocyte is selected to complete meiosis I to form a secondary oocyte (1N,2C) and a first polar body. Option D. Secondary oocyte is formed Secondary oocytes are the immature ovum shortly after ovulation, to fertilization, where it turns into an ootid. The secondary oocyte is the largest cell in the body, and in humans is just visible to the naked eye.</p>\n<p><strong>Extraedge:</strong></p><p>F ertilization is the process of fusion of male and female gametes (pronuclei) to form a zygote. It takes place within 24 hours of ovulation, in the most dilated part of the uterine tube—the ampulla . The results of fertilization are (a) determination of the genetic sex of the embryo, (b) restoration of the diploid number of chromosomes, and (c) initiation of cleavage.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Covering of the Graafian follicle is all, except", "options": [{"label": "A", "text": "Theca Interna", "correct": false}, {"label": "B", "text": "Theca Externa", "correct": false}, {"label": "C", "text": "Germinal cells", "correct": true}, {"label": "D", "text": "Granulosa cells", "correct": false}], "correct_answer": "C. Germinal cells", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Germinal cells A germ cell is any cell that gives rise to the gametes of an organism that reproduces sexually. In many animals, the germ cells originate in the primitive streak and migrate via the gut of an embryo to the developing gonads. There, they undergo meiosis, followed by cellular differentiation into mature gametes, either eggs or sperm. Germinal cells do not form a Covering of the Graafian follicle.</p>\n<p><strong>Highyeild:</strong></p><p>Graafian Follicle Coverings from outside to inwards are: Theca Externa Theca Interna Membrana granulosa Cumulus Ovaricus Zona pellucida Graafian Follicle</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Theca Interna Option B. Theca externa Option D. Granulosa cells Options A, B, and D all form layers of the Graafian follicle, as shown below.</p>\n<p><strong>Extraedge:</strong></p><p>Mature/Graafian follicle: Around the 7th day of the sexual cycle one of the tertiary follicles increases in size in response to FSH and LH and forms the largest mature follicle that is known as “Graafian follicle”. The remaining follicles degenerate and become atretic.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following structures retains almost all of the cytoplasm after the first meiotic division during the maturation of the oocytes?", "options": [{"label": "A", "text": "First Polar Body", "correct": false}, {"label": "B", "text": "Ovum", "correct": true}, {"label": "C", "text": "Primary oocyte", "correct": false}, {"label": "D", "text": "Second polar body", "correct": false}], "correct_answer": "B. Ovum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ovum Ovulation takes place while the oocyte is in metaphase. The secondary oocyte remains arrested in metaphase till fertilization occurs. The second meiotic division is completed only if fertilization occurs. This division results in two unequal daughter cells. The larger cell is called the The smaller daughter cell is called the second polar body. The ovum retains almost all of the cytoplasm whereas the first polar body does not. The first polar body may also divide during the second meiotic division making a total of three polar bodies.</p>\n<p><strong>Highyeild:</strong></p><p>If fertilization does not occur, the secondary oocyte fails to complete the second meiotic division and degenerates about 24 hours after ovulation.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. The first meiotic division results in two secondary oocytes: the ovum retains almost all of the cytoplasm whereas the first polar body (choice A) does not. Option: C. Primary oocytes (choice C) are the cells undergoing the first meiotic division. Option: D. The second polar body (choice D) is formed after the second meiotic division. The zygote is the fertilized ovum.</p>\n<p><strong>Extraedge:</strong></p><p>The development of a new individual begins at the movement when one male gamete (sperm or spermatozoon) meets and fuses with one female gamete (ovum or oocyte). The process of fusion of male and female gametes is called fertilization.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 29 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The predominant protein in myelin in the peripheral nervous system is Protein zero (P0) and its function is to stabilize adjacent plasma membranes by interaction with similar P0 molecules. Which of the following cells manufactures P0?", "options": [{"label": "A", "text": "Fibrous Astrocytes", "correct": false}, {"label": "B", "text": "Microglia", "correct": false}, {"label": "C", "text": "Oligodendrocytes", "correct": false}, {"label": "D", "text": "Schwann cells", "correct": true}], "correct_answer": "D. Schwann cells", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Schwann cells Schwann cell, also called neurilemma cell, is a cell in the peripheral nervous system that produces the myelin sheath around neuronal axons and manufactures proteolipid protein in the peripheral nervous system.</p>\n<p><strong>Highyeild:</strong></p><p>Development of various cells of nervous tissue Neuroepithelial derivatives (from the wall of the neural tube) Neural crest derivatives Mesodermal/ Mesenchymal derivatives A. Neuron bodies inside CNS A. Neuron bodies outside CNS Microglia 1. Multipolar neurons 1. Dorsal root ganglia 2. Bipolar neurons 2. Sensory ganglia of cranial nerves 5th, 7th to 10th 3. Preganglionic sympathetic and parasympathetic neurons 3. Autonomic ganglia- postganglionic sympathetic and parasympathetic neurons B. Neuroglia of CNS B. Neuroglia of PNS 1. Protoplasmic and fibrous astrocytes 1. Satellite cells 2. Oligodendrocytes 2. Schwann cells 3. Ependymal cells</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: C. Oligodendrocytes manufacture the proteolipid protein, the functional equivalent to P0 in the central nervous system. Option: A. Fibrous and protoplasmic astrocytes are supportive cells which play a role in the regulation of brain metabolism. Option: B. Microglia are mesodermal in origin and have phagocytic activity in the central nervous system.</p>\n<p><strong>Extraedge:</strong></p><p>Nerve fibres, which remain within the brain and spinal cord, receive support from and are ensheathed by neuroglial cells. The nerve fibres, which leave the central nervous system to become constituents of peripheral nerves, acquire a special sheath called the neurolemma. This sheath is derived from cells of neural crest origin called Schwann cells.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which deficits are seen in a medial medullary syndrome that involves a left-sided branch of the anterior spinal artery?", "options": [{"label": "A", "text": "Deviation of the tongue to the left, hemiplegia of arm and leg on the left", "correct": false}, {"label": "B", "text": "Deviation of the tongue to the right, hemiplegia of arm and leg on the right", "correct": false}, {"label": "C", "text": "Loss of conscious proprioception and precise tactile discrimination over the right side of the body exclusive of the face", "correct": true}, {"label": "D", "text": "Only deviation of the tongue to the left", "correct": false}], "correct_answer": "C. Loss of conscious proprioception and precise tactile discrimination over the right side of the body exclusive of the face", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Loss of conscious proprioception and precise tactile discrimination over the right side of the body exclusive of the face A vascular lesion affecting the left caudal medulla involves the left medial lemniscus, left hypoglossal nerve fibres, and the left medullary pyramid. Involvement of the left medial lemniscus produces somatosensory deficits involving the right side of the body.</p>\n<p><strong>Highyeild:</strong></p><p>Medial medullary/Dejerine syndrome: It occurs due to blockage of an anterior spinal artery. Features are Contralateral hemiplegia due to damage to the pyramid of the medulla. Loss of sense of vibration and position due to damage to the medial lemniscus. Paralysis Of Muscles of the tongue on the same side due to injury to XII cranial nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options: A & B. Damage to the left hypoglossal nerve would result in deviation of the protruded tongue to the left (and other lower motor neuron signs), and damage to the left pyramid results in right hemiplegia .along with other upper motor neuron signs. Option: D. are incorrect because they fail to combine the involvement of the tongue and contralateral hemiplegia</p>\n<p><strong>Extraedge:</strong></p><p>Lateral medullary/Wallenburg syndrome : Occurs due to blockage of a posterior inferior cerebellar artery. It supplies areas behind the inferior olivary nucleus. Features are Ipsilateral paralysis of most muscles of the soft palate, pharynx and larynx due to injury to the nucleus ambiguus which gives fibres to IX, X and XI cranial nerves. Loss of pain and temperature on the same side of the face due to the involvement of the spinal nucleus and spinal tract of the trigeminal nerve. Loss of pain and temperature on the opposite side of the body due to the involvement of the lateral spinothalamic tract.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Occlusion of which vessels affects the entire dorsolateral part of the rostral medulla level of the restiform body and produces the lateral medullary Wallenberg syndrome?", "options": [{"label": "A", "text": "Anterior inferior cerebellar artery", "correct": false}, {"label": "B", "text": "Anterior spinal artery", "correct": false}, {"label": "C", "text": "Posterior inferior cerebellar artery", "correct": true}, {"label": "D", "text": "Posterior spinal artery", "correct": false}], "correct_answer": "C. Posterior inferior cerebellar artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior inferior cerebellar artery The posterior inferior cerebellar artery supplies the rostral, dorsolateral medulla.</p>\n<p><strong>Highyeild:</strong></p><p>The posterior inferior cerebellar artery (PICA) is the largest branch of the vertebral artery. It is one of the three main arteries that supply blood to the cerebellum, a part of the brain. Blockage of the posterior inferior cerebellar artery can result in a type of stroke called lateral medullary syndrome.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option: A. Anterior inferior cerebellar artery The anterior inferior cerebellar and superior cerebellar arteries supply portions of the pons and mesencephalon although Wallenberg syndrome is called PICA syndrome; the most commonly involved vessel is the vertebral artery. Option: B. Anterior spinal artery Option: D. Posterior spinal artery The posterior spinal and anterior spinal arteries supply dorsal and ventral portions, respectively, of the caudal medulla.</p>\n<p><strong>Extraedge:</strong></p><p>The vertebral arteries are part of the circulatory system. They carry blood to the brain and spinal cord, which are part of the nervous system. The vertebral artery provides 20% of blood flow to your brain (the carotid artery supplies the other 80%). The vertebral arteries have many small branches</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 67-year-old male, known as a diabetic comes to the doctor for the treatment of an ulcer, which he developed while working in his workshop of wooden furniture. He says that he does not know when he got injured. While doing the sensory examination of the patient it was found the patient did not have a sensation of pain of touch on the plantar surface of the foot but had intact touch and pain sensation in the upper limb. Which functional component or nervous system has been affected?", "options": [{"label": "A", "text": "Afferent Component", "correct": true}, {"label": "B", "text": "Efferent component", "correct": false}, {"label": "C", "text": "Both", "correct": false}, {"label": "D", "text": "Lesion is in the CNS", "correct": false}], "correct_answer": "A. Afferent Component", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Afferent Component The anatomically nervous system is divided into two parts: A) CNS B) PNS PNS is again divided into two components A) Afferent- provides sensory information to CNS B) efferent- carries motor information from CNS to muscles, viscera, blood vessels etc. So injury to afferent components results in loss of sensation of touch and pain.</p>\n<p><strong>Highyeild:</strong></p><p>According to the number of their Processes, neurons are classified as Multipolar neurons. Most of the neurons in man are multipolar, e.g. all motor and internuncial neurons. Bipolar neurons are confined to the first neuron of the retina, the ganglia of the eighth cranial nerve, and the olfactory mucosa. Pseudounipolar neurons are actually unipolar, to begin with, but become bipolar functionally and are found in the dorsal nerve root ganglia and sensory ganglia of the cranial nerves. Unipolar neurons are present in the mesencephalic nucleus of the trigeminal nerve and also occur during fetal life. These cells are more common in lower vertebrates.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option: B. Efferent component The anatomically nervous system is divided into two parts: CNS PNS PNS is again divided into two components Afferent- provides sensory information to CNS efferent- carries motor information from CNS to muscles, viscera, blood vessels etc Injury to efferent components result in a decrease in muscle tone or paralysis as seen in poliomyelitis. Option: C. Both If both components of the peripheral nervous system are affected then the result in sensory as well as motor deficits like seen in demyelinating diseases such as multiple sclerosis etc. Option: D. Lesion in the CNS If the lesion is present in the CNS, in the cortex, midbrain or brainstem. Then manifestation would be of multisystem in such a lesion.</p>\n<p><strong>Extraedge:</strong></p><p>Types of neuroglial cells Protoplasmic astrocyte Fibrous astrocyte Oligodendrocyte Microglia Cell size Large Large Medium Small, elongated Shape of nucleus Oval, lightly stained Oval, lightly stained Small, spherical, dark stained Small, elongated, dark stained Cytoplasmic processes Many, short and thick Many long slender Few, short, beaded Short, thin, spinous Cytoplasm Granular Fibrillar - Situation Grey matter White matter White matter Grey and white matters Function The blood-brain barrier (BBB) BBB Myelination Phagocytosis Embryological origin Neural crest Neural crest Neural crest Mesoderm</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A young female patient of age 8 years comes to the OPD, with complaints of extensive growth of hair in his back. The clinical examination of motor and sensory arts was within physiological limits. Patients had no complaints otherwise, and the growth of patients was normal as per her age. What is the most likely reason for this development?", "options": [{"label": "A", "text": "Idiopathic Etiology", "correct": false}, {"label": "B", "text": "X-linked congenital hypertrichosis syndrome", "correct": false}, {"label": "C", "text": "Part of vestigial tail", "correct": false}, {"label": "D", "text": "Neural tube defect", "correct": true}], "correct_answer": "D. Neural tube defect", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392203280-QTDA062005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Neural tube defect Neural tube defect is the result of the failure of the embryonic halves of one or more neural arches to fuse in the median plane Spina bifida occulta occurs in the L5 or S1 vertebra in approximately 10% of otherwise normal people. In its most minor form, the only evidence of its presence may be a small dimple with a tuft of hair arising from it an overlying lipoma, dermal sinus, or other birthmarks may also occur. Spina bifida Occulta usually produces no symptoms. A small percentage of affected infants have functionally significant defects of the underlying spinal cord and dorsal roots.</p>\n<p><strong>Highyeild:</strong></p><p>Divisions of the nervous system</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Idiopathic Etiology This can be a possibility but first or foremost we need to rule out other causes. If we do not find any cause then only we have to label it as idiopathic pathology. Option: B. X-LINKED CONGENITAL HYPERTRICHOSIS SYNDROME Congenital generalized hypertrichosis (CGH) is a genetically and phenotypically heterogeneous group of rare conditions characterized by universal hair overgrowth. It is generalized hair overgrowth rather than localized Option: C. Part Of Vestigial Tail The human tail is a caudal, vestigial, midline protrusion with skin covering a combination of muscle and adipose tissue. It may be a ‘true tail’ or a ‘pseudo-tail’. Pseudo-tails are lesions of various types coincidentally found in the caudal region of newborns, often associated with the spinal column and coccygeal malformations. The true human tail is characterized by a complex arrangement of adipose and connective tissue, central bundles of longitudinally arranged striated muscle in the core, blood vessels, nerve fibres, nerve ganglion cells and specialized pressure-sensing nerve organs (Pacini corpuscles). It is covered by normal skin, replete with hair follicles, sweat glands and sebaceous glands.</p>\n<p><strong>Extraedge:</strong></p><p>Myasthenia gravis: It is a consequence of auto-immune destruction of nicotinic postsynaptic receptors for acetylcholine. Thymus abnormality occurs in 80% of patients. Clinical features: Limb and trunk: Weakness of neck muscles resulting in lolling of the Proximal limb muscles are preferentially affected. Limb reflexes are hyperactive. Muscle wasting occurs in 15% of cases. Diagnosis: Acetylcholine receptor antibodies are detected in the majority of patients.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A twenty-year-old second gravida presented to the department of radiodiagnosis for routine obstetric ultrasonography. Her first child was a girl and normal. There was no history of consanguinity of marriage. Her general physical examination was within normal limits. On clinical examination, the gestational age corresponded to 16–18 weeks. Ultrasonography revealed a single live intrauterine fetus with an average gestational age corresponding to 17 weeks. The fetal skull bones were poorly ossified. The supratentorial brain was replaced by CSF with a thin rim of peripheral cerebral parenchyma and a large central mono ventricle, with fused thalami. Which structure failed to form in this congenital anomaly?", "options": [{"label": "A", "text": "Telencephalon", "correct": true}, {"label": "B", "text": "Procencephalon", "correct": false}, {"label": "C", "text": "Rhombencephalon", "correct": false}, {"label": "D", "text": "Diencephalon", "correct": false}], "correct_answer": "A. Telencephalon", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Telencephalon Failure in the formation of telencephalon from Prosencephalon is called holoprosencephalopathy. Holoprosencephalopathy (HPS) results from incomplete separation of the cerebral hemispheres. It is associated with facial abnormalities. Genetic and environmental factors have been implicated in this severe and relatively common ( fetuses and live births) developmental defect. Maternal diabetes and teratogens, such as high doses of alcohol, can destroy embryonic cells in the median plane of the embryonic disc during the third week, producing a wide range of birth defects resulting from the defective formation of the forebrain. In alobar holoprosencephaly, the forebrain is small and the lateral ventricles often merge to form one large ventricle.</p>\n<p><strong>Highyeild:</strong></p><p>Holoprosencephaly ( HPE ) is a cephalic disorder in which the prosencephalon (the forebrain of the embryo) fails to develop into two hemispheres, typically occurring between the 18th and 28th day of gestation. Normally, the forebrain is formed and the face begins to develop in the fifth and sixth weeks of human pregnancy. Holoprosencephaly is estimated to occur in approximately 1 in every 250 conceptions and most cases are not compatible with life and result in fetal death in utero due to deformities to the skull and brain. However, holoprosencephaly is still estimated to occur in approximately 1 in every 8,000 live births.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Prosencephalon Failure to form Procencephalon is called macroencephaly. It is a severe defect of the calvaria and brain that results from failure of the rostral neuropore to close during the fourth week. As a result, the forebrain, midbrain, most of the hindbrain and calvaria are absent Here there is no absence of formation but due to abnormal vascularisation, Prosencephalon undergoes degeneration. Option: C. Rhombencephalon No such defects have been mentioned in the medical literature. Option: D. Diencephalon Failure to form diencephalon results in the absence of a third ventricle. The absence of the third ventricle is often associated with holoprosencephalopathy. A child presents with hydrocephalus, seizures, mental retardation etc.</p>\n<p><strong>Extraedge:</strong></p><p>Symptoms of holoprosencephaly range from mild (no facial/organ defects, anosmia, or only a single central incisor) to moderate to severe (cyclopia). The symptoms are dependent upon the classification type. There are four classifications of holoprosencephaly as well as a mild \"microform\". Alobar- Most severe form includes the formation of synophthalmia (a single central eye), proboscis, and severe impairment. Semilobar - Can present with a severely decreased distance between the eyes, a flat nasal bridge, eye defects, cleft lip and palate, and severe impairment. Lobar - Can present with decreased distance between eyes, a flat nasal bridge, and closely spaced nostrils, mental and locomotion delays may be present. Syntelencephaly or middle interhemispheric variant of holoprosencephaly (MIHV)- Mild phenotypic presentation which can present with flat nasal bridge, metopic prominence, shallow philtrum, and possibly mental and locomotion delays. \" Microform\"- Mild phenotypic presentation with reduced distance between eyes, sharp nasal bridge, single maxillary central incisor.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 75-year-old man comes to the emergency department with the complaint of paralysis of one side of his whole body. MRI brain found an infarction of the motor cortex. Why did he not have pain from the infarction?", "options": [{"label": "A", "text": "There is a non-release of chemical mediators of pain", "correct": false}, {"label": "B", "text": "There is the absence of pain fibres", "correct": true}, {"label": "C", "text": "Both a and b", "correct": false}, {"label": "D", "text": "None", "correct": false}], "correct_answer": "B. There is the absence of pain fibres", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>There is the absence of pain fibres There are no pain receptors or fibres located in the brain. Injury to the brain causes the release of pain mediators but due to the absence of pain fibres, no pain is felt. Hence, during infarction no pain is felt in the brain. But there is the presence of pain fibres in the meninges resulting in pain during raised ICP.</p>\n<p><strong>Highyeild:</strong></p><p>Main Somatosensory Pathways to Consciousness Sensation Receptor First-Order Neuron Second-Order Neuron Third-Order Neuron Pathways Destination Pain and temperature Free nerve endings Posterior root ganglion Substantia gelatinosa Ventral posterolateral nucleus of thalamus Lateral spinothalamic, spinal lemniscus Posterior central gyrus Light touch and pressure Free nerve endings Posterior root ganglion Substantia gelatinosa Ventral posterolateral nucleus of thalamus Anterior spinothalamic, spinal lemniscus Posterior central gyrus Discriminative touch, vibratory sense, conscious muscle joint sense Meissner corpuscles, pacinian corpuscles, muscle spindles, tendon organs Posterior root ganglion Nuclei gracilis and cuneatus Ventral posterolateral nucleus of thalamus Fasciculi gracilis and cuneatus, medial lemniscus Posterior central gyrus</p>\n<p><strong>Extraedge:</strong></p><p>The meninges of the brain and spinal cord form three concentric membranous coverings. The outermost covering, the dura mater, by virtue of its toughness, serves to protect the underlying nervous tissue. The dura protects the cranial nerves by forming a sheath that covers each cranial nerve for a short distance as It passes through foramina In the skull. The dura mater also provides each spinal nerve root with a protective sheath. In the skull, the falx cerebri, which is a vertical sheet of dura between the cerebral hemispheres, and the tentorium Cerebelll, which is a horizontal sheet that projects forward between the cerebrum and cerebellum, serve to limit excessive movements of the brain the skull. The arachnoid mater is a much thinner impermeable membrane that loosely covers the brain. The interval between the arachnoid and pia mater. the subarachnoid space is filled with CSF. The CSF gives buoyancy to the brain and protects the nervous tissue from mechanical forces applied to the skull. The pia mater is a vascular membrane that closely invests and supports the brain and spinal cord.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 16-year-old boy was hit by a scooter. He was unconscious for a period of half an hour and vomited thrice. He was a known case of juvenile diabetes mellitus on examination in the casualty, the patient was conscious and moved all 4 limbs. His pulse was 82/min and BP 130/80 mm of hg. CT scan done within 6 hours showed mild cerebral edema and a scalp contusion in the left frontal region. There were no fractures. He was observed in the ward and was given intravenous mannitol. The patient was alright for 48 hours after the accident. On the 3rd day, he started vomiting again, his GCS dropped to 12/15 and he developed bradycardia. A repeat CT scan, after 50 hours of the first CT, showed a moderately sized anterior fossa extradural hematoma at the site of the (left) frontal scalp contusion. By the time he was taken for surgery, GCS had dropped to 9/15.what was the reason for rapidly progressing extradural hematoma?", "options": [{"label": "A", "text": "Resistance due to adhesion of the dura mater with the periosteum of the skull", "correct": true}, {"label": "B", "text": "Because of the presence of comorbidities", "correct": false}, {"label": "C", "text": "Because of the wrong treatment", "correct": false}, {"label": "D", "text": "Because of misdiagnosis", "correct": false}], "correct_answer": "A. Resistance due to adhesion of the dura mater with the periosteum of the skull", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Resistance due to adhesion of the dura mater with the periosteum of the skull The dura mater is the outermost layer of the meninges, lying directly underneath the bones of the skull and vertebral column. It is thick, tough and inextensible. Within the cranial cavity, the dura contains two connective tissue sheets: Periosteal layer – lines the inner surface of the bones of the cranium. Meningeal layer – deep to the periosteal layer inside the cranial cavity. It is the only layer present in the vertebral column. Between these two layers, the dural venous sinuses are located. They are responsible for the venous vasculature of the cranium, draining into the internal jugular veins. In some areas within the skull, the meningeal layer of the dura mater folds inwards as dural reflections. They partition the brain and divide the cranial cavity into several compartments. For example, the tentorium Cerebelli divides the cranial cavity into supratentorial and infratentorial compartments. The dura mater receives its own blood supply – primarily from the middle meningeal artery and vein. It is innervated by the trigeminal nerve (v1, v2 and v3). Hence, Extradural hematoma is a rapidly expanding mass and forms a medical emergency due to 1) Resistance produced by attachment of dura mater to the periosteum of the skull 2) Intense arterial pressure</p>\n<p><strong>Highyeild:</strong></p><p>Migraine Headache Migraine Is a common form of headache, which may be unilateral or bilateral, recurring at Intervals and associated with prodromal visual disturbances. The prodromal visual disturbances are thought to be due to sympathetic vasoconstriction of the cerebral arteries supplying the visual cortex. The headache is chiefly due to the dilation and stretching of other cerebral arteries and branches of the external carotid artery. The disease, therefore, appears to affect arteries both inside and outside the skull, and its cause is unknown, although genetic, hormonal, and biochemical factors may initiate an attack. Beta-blockers bring relief to some patients due to the reduction In cerebral vasodilation.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Because of the presence of comorbidities Patients with hypotension, antiplatelet therapy, skull fractures, uncontrolled hypertension, and polytrauma, are considered some of the risk factors for progressive extradural hematoma. Here, the patient is a known case of diabetes mellitus. Diabetes mellitus is not a risk factor for progressive extradural hematoma. Option: C. Because of wrong the treatment In extradural hematoma, due to raised ICP, patients are required to give intravenous mannitol. If coagulopathy or persistent bleeding may require administration of vitamin K, protamine sulfate, fresh frozen plasma, platelet transfusions, or clotting factor concentrate. Minimally invasive surgical procedures, including the use of burr holes and negative pressure drainage, may be used in selected cases. Craniotomy or laminectomy can also be done followed by evacuation of the hematoma, coagulation of bleeding sites, and inspection of the dura. Option: D. Because of misdiagnosis Following in this list of differential diagnoses in the given case: Extradural hematoma Head injury Intracranial epidural abscess Intracerebral haemorrhage Posttraumatic epilepsy Spinal cord haemorrhage Transient ischemic attack But due to the presence of a history of minor trauma, and evidence from a CT scan, the most likely diagnosis is an extradural hematoma.</p>\n<p><strong>Extraedge:</strong></p><p>Alcoholic Headache Alcoholic headache is due to the direct toxic effect of alcohol on the meninges.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 75-year-old man working as a mine worker comes to the emergency due to the development of sudden unconsciousness. The patient is a known case of hypertension and diabetes mellitus, hyperlipidemia and COPD. The GCS was 10. There was no history of trauma or coagulopathy. The patient went under an urgent MRI which revealed left-sided basal ganglia hemorrhage. The patient was admitted to the ICU. After 10 hours, the condition of the patient deteriorated and the patient was kept on a ventilator. CT scan revealed transtentorial herniation of the brain. What could be the most probable cause of deterioration?", "options": [{"label": "A", "text": "Herniation of the brain causing compression of the brainstem", "correct": true}, {"label": "B", "text": "Because of a ischaemic attack of the brainstem", "correct": false}, {"label": "C", "text": "Because of embolism", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Herniation of the brain causing compression of the brainstem", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Herniation of the brain causing compression of the brainstem The arrangement of dural partitions such as the falx cerebri and tentorium cerebelli may help to stabilize the brain within the cranial cavity. However, when there is focal brain swelling or a focal space-occupying lesion within the brain or cranial cavity, mass effect and raised intracranial pressure may cause the brain to herniate under the falx Cerebri or, more significantly, through the tentorial incisura. A transtentorial herniation is a type of cerebral herniation broadly divided into two major types based on the direction of herniation: downwards due to supratentorial mass effect and upward due to infratentorial mass effect. Downward transtentorial herniation Downward herniation occurs when there is a mass effect upon or from within the cerebral hemispheres. The pattern of herniation can be divided into lateral and central herniation. Lateral herniation Lateral herniation occurs due to unilateral or asymmetric mass effects. The medial parts of the temporal lobe are pushed into the ambient cistern and up against the brainstem. This can be further divided according to whether the herniation is predominantly anterior (uncal herniation), which is most common, or posterior (posterior parahippocampal gyrus and anterior part of the lingual gyrus ). Central herniation Central herniation occurs when there is a symmetric or severe mass effect resulting in the downward displacement of the thalami and midbrain. Upward transtentorial herniation Ascending transtentorial herniation occurs due to mass effect within the posterior fossa.</p>\n<p><strong>Highyeild:</strong></p><p>Damage to the brainstem results in characteristic deficits that form part of the so-called herniation syndromes. The falx cerebri and tentorium Cerebelli incompletely partition the intracranial volume into partially communicating compartments. The tentorium Cerebelli incompletely separates the intracranial volume into the supratentorial space (above) and the infratentorial space (below). The supratentorial space is partially partitioned into left and right halves by the falx Cerebri. The supra and infratentorial spaces communicate through a narrow opening in the tentorium, the tentorial notch or incisura. The infratentorial compartment is continuous inferiorly with the intraspinal compartment through the small foramen magnum.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Because of an ischaemic attack of the brainstem Option: C. Because of embolism Option: D. None of the above Options B, C and D. are incorrect answers because in the above case, a CT scan revealed transtentorial herniation of the brain.</p>\n<p><strong>Extraedge:</strong></p><p>The pressure increase in the posterior fossa, an infratentorial location, may result in herniation upwards through the tentorial notch or downwards into the foramen magnum. Upward cerebellar herniation displaces the brainstem against the tentorium and into the notch with resultant symptoms of increased intracranial pressure, paralysis of upward gaze, motor deficits and altered consciousness. Extrusion of the cerebellar tonsils downwards into the foramen magnum may result in damage to medullary cardiac and respiratory centres, with resultant changes in heart and respiratory rates. Both of these syndromes may constitute a medical emergency, the former due to rapidly developing hydrocephalus, the latter due to compromise of cardiac and respiratory centres.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 22-year-old man with a severe headache and scalp bleeding after a head chop wound. Physical examination identified a 20-cm straight laceration in his Parieto occipital scalp. Computed tomography (CT) demonstrated a depressed cranial fracture (DCF) in the left Parieto occipital bone, a fracture line across the midline to the right side, and penetrations of bone fragments into the brain parenchyma. Which venous sinus is most likely to be injured?", "options": [{"label": "A", "text": "Sigmoid Sinus", "correct": true}, {"label": "B", "text": "Cavernous sinus", "correct": false}, {"label": "C", "text": "Occipital sinus", "correct": false}, {"label": "D", "text": "Intercavernous sinus", "correct": false}], "correct_answer": "A. Sigmoid Sinus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sigmoid Sinus The sigmoid sinuses are continuations of the transverse sinuses, beginning where these leave the tentorium cerebelli Each sigmoid sinus curves inferomedially in a groove on the mastoid process of the temporal bone, crosses the jugular process of the occipital bone and turns forwards to the superior jugular bulb, lying posterior in the jugular foramen. Anteriorly, a thin plate of bone separates its upper part from the mastoid antrum and air cells. It connects with pericranial veins via mastoid and condylar emissary veins Due to such an anatomical position of the sigmoid sinus, skull fractures in the Parieto occipital region cause bleeding in the sigmoid sinus. Dural venous sinuses</p>\n<p><strong>Highyeild:</strong></p><p>The meningeal layer sends inwards following folds of dura mater Folds Shape Attachments Venous sinuses enclosed Falx cerebri (Fig. 2.1) Sickle-shaped, separates the right from the left cerebral hemisphere Superior, convex margins are attached to the sides of the groove lodging the superior sagittal sinus The inferior concave margin is free anterior attachment is to the crista galli and frontal crest Posterior attachment is to the upper surface of cerebelli tentorium Superior sagittal sinus Inferior sagittal sinus Straight sinus Tentorium cerebelli (Fig. 2.1) Tent-shaped, separates the cerebral hemispheres from the hindbrain and the lower part of the midbrain Lifts off the weight of occipital lobes from the cerebellum Has a free anterior margin. Its ends are attached to anterior clinoid processes Rest is free and concave Posterior margin is attached to the lips of the groove containing transverse sinuses, superior petrosal sinuses and posterior clinoid processes Transverse sinuses, Superior petrosal sinuses Falx cerebelli Small sickle-shaped fold partly separating two cerebellar hemispheres The base is attached to the posterior part of the inferior surface of tentorium cerebelli Apex reaches till foramen magnum Occipital sinus Diaphragma sellae (Fig. 2.1) Small horizontal fold Anterior attachment is to tuberculum sellae Posterior attachment is to dorsum sellae laterally continuous with dura mater of middle cranial fossa Anterior and posterior intercavernous sinuses</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Cavernous sinus The cavernous sinuses are located within the middle cranial fossa, on either side of the sella turcica of the sphenoid bone (which contains the pituitary gland). They are enclosed by the endosteal and meningeal layers of the dura mater Option: C. Occipital sinus The occipital sinus is the smallest of the sinuses and it is typically larger in children. It lies in the attached margin of the falx Cerebelli. It commences near the foramen magnum in several small channels, one joining the end of the sigmoid sinus. It connects with the internal vertebral plexuses. It ends in the confluence of the sinuses. Option: D. Intercavernous sinus The two cavernous sinuses are connected by the superior, inferior and posterior intercavernous sinuses and the basilar plexus. The superior and posterior intercavernous sinuses lie in the anterior and posterior attached borders of the diaphragm sellae and they thus form a complete circular venous sinus. The inferior intercavernous sinuses are irregular and plexiform in nature, and commonly encountered in a surgical transnasal approach to the pituitary gland. Obliteration of any intercavernous sinus has no clinical consequences because all connections are valveless and the direction of flow in them is reversible.</p>\n<p><strong>Extraedge:</strong></p><p>Circulation of cerebrospinal fluid (CSF)</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An 18-year-old high school football player, with an unremarkable medical history, who was 181 cm tall and weighed 84 kg. While walking toward the sideline, the athlete took off his helmet and appeared confused. Falling to his knees, he began to vomit. However, the patient was oriented to time, person, and place. His immediate complaints included severe head pain, nausea, and vertigo. No neck pain or any lower or upper extremity paresthesias were present. The patient had a history of 2 minor trauma with the ball while playing the game. What could be the most probable diagnosis?", "options": [{"label": "A", "text": "Skull Fracture", "correct": false}, {"label": "B", "text": "Intracerebral haemorrhage", "correct": false}, {"label": "C", "text": "Subdural hematoma", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. Subdural hematoma", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Subdural hematoma The meningeal layer of the dura mater is usually adherent to the underlying arachnoid mater via a series of tight junctions. The subdural space does not exist under normal circumstances and is appreciable only when there is underlying pathology. Bridging veins drain from the underlying brain to the dura mater and the superior sagittal sinus. They have a relatively straight course and do not allow for much movement of the underlying brain tissue. Thus, they are easily placed under high tension. This is particularly important in the elderly where the underlying atrophic brain places these vessels under higher-than-normal tension. Bleeding from bridging veins may strip the dura from the arachnoid mater. This collection of blood is known as a subdural haematoma. Separation of the arachnoid and dura mater requires little physical force, which means that damage to small bridging veins in the space can result in subdural haematoma after even relatively mild head trauma. In many cases, there is some predisposing factor, such as cerebral atrophy or increased size of the underlying subarachnoid space.</p>\n<p><strong>Highyeild:</strong></p><p>Types of intracranial haemorrhage Type of haemorrhage Vessels/vessels most commonly involved Extradural haemorrhage Rupture of the anterior division of the middle meningeal artery Subdural haemorrhage Tearing of superior cerebral (bridging) veins Subarachnoid haemorrhage Leakage or rupture of congenital berry aneurysms on the arterial circle of Willis Intracerebral (cerebral) haemorrhage Rupture of thin-walled lenticulostriate artery (Charcot's artery of cerebral haemorrhage), a branch of the middle cerebral artery</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Skull fracture: This answer is less likely as there was no external bleeding wound seen on examination. Also, the trauma was minor in nature, so less likely to cause a skull fracture Option: B. Intracerebral haemorrhage There is no evidence of intracerebral haemorrhage followed by trauma in the literature. Intracerebral haemorrhage is mainly due to systemic diseases like uncontrolled hypertension, diabetes mellitus, hyperlipidemia, antiplatelet therapy, coagulopathy etc. Option: D. None of the above Option: c. That is the correct answer.</p>\n<p><strong>Extraedge:</strong></p><p>The subarachnoid haemorrhage commonly occurs due to rupture of congenital berry aneurysms which develop in the arteries of the circle of Willis. Since the circle of Willis is located at the base of the brain, sub-arachnoid haemorrhage commonly occurs at the base of the brain.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An autopsy of an 80-year-old man, who died due to liver failure found that his brain was stained yellow in colour. The person has had a history of two CVA strokes in his life. What could be the reason for brain staining?", "options": [{"label": "A", "text": "Destruction of blood-brain barrier", "correct": true}, {"label": "B", "text": "Age-related staining", "correct": false}, {"label": "C", "text": "Both a and b", "correct": false}, {"label": "D", "text": "None", "correct": false}], "correct_answer": "A. Destruction of blood-brain barrier", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Destruction of blood-brain barrier Breakdown of the blood-brain barrier occurs when the brain is damaged by ischaemia or infection, and is also associated with primary and metastatic cerebral tumours. Normally, the brain, spinal cord and peripheral nerves remain unstained by the bile. However, areas of infarction will be stained by bile pigment because of the localized breakdown of the blood-brain barrier.</p>\n<p><strong>Highyeild:</strong></p><p>Structure of Blood-Brain Barrier The BBB consists of the following structures which intervene between the blood in the capillaries and the extracellular spaces surrounding the neurons and neuroglia in the brain: capillary endothelial cells and tight junctions between them. a basement membrane on which the capillary endothelial cells are arranged, and the foot processes of the astrocytes that adhere to the outer surface of the capillary wall. Structure of Blood-Brain Barrier</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - There are no colour changes in the brain due to age. The only evident age-related change in the brain is cerebral atrophy.</p>\n<p><strong>Extraedge:</strong></p><p>The drugs like, chloramphenicol, tetracyclines, sulphonamides, thiopental (lipid soluble), and atropine (lipid soluble) easily pass through the blood-brain barrier. The drugs like, phenylbutazone, and neuro-transmitters like exogenous epinephrine and dopamine cannot cross the blood-brain barrier.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Cells present in the cerebral cortex:", "options": [{"label": "A", "text": "Betz Cells", "correct": true}, {"label": "B", "text": "Purkinje cells", "correct": false}, {"label": "C", "text": "Golgi cells", "correct": false}, {"label": "D", "text": "Stellate cells", "correct": false}], "correct_answer": "A. Betz Cells", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Betz Cells Ganglionic/inner pyramidal layer of the cerebral cortex contains medium-and large-sized pyramidal cells. Large neurons called giant pyramidal cells of Betz lie in the deeper zone of the layer. In the neocortex, small pyramidal cells are located superficially; medium-sized cells are deeper, and large cells lie further deeply. Tangential fibres of the inner band of Baillarger traverse at the outer part of this layer.</p>\n<p><strong>Highyeild:</strong></p><p>Histology of cerebrum From superficial to deep, the following six layers are seen: The molecular layer consists of a few fibres and some spindle-shaped or stellate cells. The outer granular layer contains small cells, triangular in shape, with an apex directed peripherally and the base directed inwards. The axons leave the basal part of the cell. A few stellate cells are also seen. The outer pyramidal layer has cells similar to the outer granular layer, but the cells are distinctly larger than those of the outer granular layer. The inner granular layer contains cells which are larger than outer pyramidal cells, but have a large number of stellate cells between them. The inner pyramidal layer contains cells which are triangular in shape and are the largest cells of the cerebral cortex, especially in the motor cortex where these are termed the Betz cells. The fusiform layer or polymorphous layer contains mainly fusiform cells with a few stellate cells. No pyramidal cells are seen in this layer. Histology of cerebrum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Purkinje cells Option: C. Golgi cells Option: D. Stellate cells Purkinje cells, Golgi cells and Stellate cells are present in the cerebellar cortex.</p>\n<p><strong>Extraedge:</strong></p><p>The granular cell layers of the cerebral cortex are afferent in connection and the pyramidal cell layers are efferent in nature. The pyramidal cells are more pronounced in the motor areas, whereas the granular cells are more conspicuous in the sensory areas of the brain. In between the nerve cells are the nerve fibres of these cells and capillaries. The neuroglial elements are protoplasmic astrocytes, oligodendroglia and microglia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient with unilateral upper motor neuron paralysis of the facial muscles can smile with both sides of his face in response to a joke but not voluntarily. This can be explained by the following facts:", "options": [{"label": "A", "text": "The main corticobulbar fibres controlling the voluntary movement of the facial muscles have been preserved.", "correct": false}, {"label": "B", "text": "Reticular fibres, possibly originating in the hypothalamus and descending to the motor nuclei of the facial nerves, are damaged.", "correct": false}, {"label": "C", "text": "The facial nerves are damaged.", "correct": false}, {"label": "D", "text": "The muscles producing mimetic movements of the face are innervated by corticobulbar fibres that have a course separate from the main corticobulbar fibres", "correct": true}], "correct_answer": "D. The muscles producing mimetic movements of the face are innervated by corticobulbar fibres that have a course separate from the main corticobulbar fibres", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The muscles producing mimetic movements of the face are innervated by corticobulbar fibres that have a course separate from the main corticobulbar fibres In this patient, the muscles producing the mimetic movements of the face are innervated by corticobulbar fibres that have a course separate from that of the main corticobulbar fibres. In patients with hemiplegia, the emotional movements of the face are usually preserved. This indicates that the upper motor neurons controlling these mimetic movements have a course separate from that of the main corticobulbar fibres. A lesion involving this separate pathway alone results In a loss of emotional movements, but voluntary movements are preserved. A more extensive lesion will produce both mimetic and voluntary facial paralysis.</p>\n<p><strong>Highyeild:</strong></p><p>BEll’s PALSY Bell palsy is a dysfunction of the facial nerve, as it lies within the facial canal; it is usually The site of the dysfunction will determine the aspects of facial nerve function that do not work. The swelling of the nerve within the bony canal causes pressure on the nerve fibres; this results in a temporary loss of function of the nerve, producing a lower motor neuron type of facial paralysis. The cause of Bell's palsy is not known; it sometimes follows exposure of the face to a cold draft.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The main corticobulbar fibres controlling the movements of the voluntary facial muscles in this patient have been destroyed. Option: B. The reticular fibres, possibly originating in the hypothalamus and descending to the motor nuclei of the facial nerves, are Intact. Option: C. The facial nerves are intact since this patient is able to move the facial muscles</p>\n<p><strong>Extraedge:</strong></p><p>TRIGEMINAL NEURALGIA In trigeminal neuralgia, the severe, stabbing pain over the face is of unknown cause and Involves the pain fibres of the trigeminal nerve. Pain is felt most commonly over the skin area innervated. by the mandibular and maxillary divisions of the trigeminal nerve; only rarely is pain felt In the area supplied by the ophthalmic division.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old female patient develops Parinaud’s syndrome (vertical gaze palsy) and an MRI shows a large tumour of her pineal gland. The tumour is not only compressing her tectum, causing the vertical gaze palsy, but also obstructing the underlying cerebrospinal fluid pathway causing progressive noncommunicating hydrocephalus. The obstruction causes immediate accumulation of cerebrospinal fluid in?", "options": [{"label": "A", "text": "Cerebral aqueduct of Sylvius", "correct": false}, {"label": "B", "text": "Fourth ventricle", "correct": false}, {"label": "C", "text": "Lateral ventricle", "correct": false}, {"label": "D", "text": "Third ventricle", "correct": true}], "correct_answer": "D. Third ventricle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Third ventricle In this situation, the cerebrospinal fluid will accumulate immediately in the third ventricle and cause hydrocephalus. The flow of cerebrospinal fluid is normally from the lateral ventricles to the third ventricle and then by way of the cerebral aqueduct of Sylvius to the fourth ventricle. From there the cerebrospinal fluid flows out of the brain into the subarachnoid space. A blockage of the cerebral aqueduct will result in the immediate accumulation of cerebrospinal fluid in the third ventricle. Because the cerebrospinal fluid no longer flows from the ventricular system to the subarachnoid space, the resulting hydrocephalus is termed non-communicating.</p>\n<p><strong>Highyeild:</strong></p><p>Circulation of cerebrospinal fluid (CSF)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Cerebral aqueduct of Sylvius Option: B. Fourth ventricle Option: C. Lateral ventricle A blockage of the cerebral aqueduct will result in immediate accumulation of cerebrospinal fluid in the third ventricle, therefore Option A, B and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Central Canal The central canal opens superiorly Into the fourth ventricle. Inferiorly, it extends through the inferior half of the medulla oblongata and through the entire length of the spinal cord. In the conus medullaris of the spinal cord, it expands to form the terminal ventricle The central canal Is closed at Its lower end, Is filled with CSF, and is lined with ependyma. The central canal is surrounded by grey matter, the grey commissure. The central canal does not have a Choroid Plexus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Hormone-secreting chromophils in the pars distalis of the adenohypophysis are classified into Acidophils and basophils. Which of the following hormones is secreted by the Acidophils?", "options": [{"label": "A", "text": "Adrenocorticotropin", "correct": false}, {"label": "B", "text": "Follicle-stimulating hormone", "correct": false}, {"label": "C", "text": "Luteinizing hormone", "correct": false}, {"label": "D", "text": "Prolactin", "correct": true}], "correct_answer": "D. Prolactin", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Prolactin Prolactin is secreted by one of the two types of hormone-secreting Acidophils, the mammotroph. The other types of Acidophils are the Somatotrophs, which secrete growth hormone (Somatotropin). The hormones listed in all the other choices are secreted by the basophils.</p>\n<p><strong>Highyeild:</strong></p><p>Pituitary gland hormones Hypothalamic Cell type Staining affinity Hormone produced Releasing hormones Inhibiting hormones Somatotrophic cells Acidophilic Somatotrophin (or Growth hormone, GH) SRH Somatostatin Mammotrophic cells Acidophilic Prolactin (PRL) PRH PIH Gonadotrophic cells Basophils Follicle-stimulating hormone (FSH); Luteinizing hormone (LH) GnRH Thyrotrophic cells Basophilic Thyrotrophin (TSH) TRH Corticotrophic cells Basophilic Corticotrophin (ACTH) CRH</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Adrenocorticotropin (choice A) is secreted by the Corticotrophs. Options: B, C. The gonadotrophs secrete either follicle-stimulating hormone (choice B) or luteinizing hormone (choice C). Thyrotropin is secreted by Thyrotrophs</p>\n<p><strong>Extraedge:</strong></p><p>Important hormones secreted by endocrine glands Endocrine gland Secretion/Hormone Pituitary gland Growth hormone, Thyroid stimulating hormone, Luteinizing hormone, Follicle- stimulating hormones, Prolactin, Adenocorticoid trophin hormone, Antidiuretic hormone, Oxytocin Hypothalamus Growth hormone Releasing hormone, Growth hormone inhibitory hormone, Thyrotropin-releasing hormone, Corticotropin-releasing hormone, Gonadotropin-releasing hormone, Pineal gland Melatonin Thymus Thymosin Parathyroid Parathyroid hormone Thyroid Thyroxine Pancreas Insulin, Glucagon Adrenal Adrenaline, Noradrenaline, Cortisone, Aldosterone Testis Testosterone Ovary Estrogen, Progestrone</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 72-year-old male patient has suffered a cerebral infarct affecting the left cerebral hemisphere. On examination of the patient, it is noticed that his verbal output is fluent and paraphrastic. His comprehension of speech is normal but repetition is severely impaired. Naming is also impaired, although when given a list, the patient is able to select the correct name. Special consultation with a neurologist results in a diagnosis of conduction aphasia. Which of the following brain structures is affected?", "options": [{"label": "A", "text": "Arcuate Fasciculus", "correct": true}, {"label": "B", "text": "Broca’s area", "correct": false}, {"label": "C", "text": "Nucleus ambiguus", "correct": false}, {"label": "D", "text": "Red nucleus", "correct": false}], "correct_answer": "A. Arcuate Fasciculus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Arcuate Fasciculus The arcuate fasciculus connects Wernicke’s area to Broca’s area, integrating comprehension of speech with motor speech. A lesion in this connecting bundle results in this unusual condition of conduction aphasia, characterized by impairment of repetition and naming.</p>\n<p><strong>Highyeild:</strong></p><p>Summary of functions and effects of damage to lobes of the brain table,tr,th,td {border:1px solid black;} Lobes of brain Functions Effects of damage Frontal Personality, emotional control, social behaviour contralateral motor control, language and micturition Lack of initiation, antisocial behaviour, impaired memory and incontinence Parietal (non-dominant) Spatial orientation, recognition of faces, appreciation of music and figures Spatial disorientation, non-recognition of faces Parietal (dominant) Language, calculation, analytical, logical, and geometrical Dyscalculia, dyslexia, apraxia (inability to do complex movements) and agnosia (inability to recognize) Temporal (non-dominant) Auditory perception, pitch perception, non-verbal memory, smell and balance Reception aphasia and impaired musical skills Temporal (dominant) Language, verbal memory and auditory perception Dyslexia, verbal memory impaired and receptive aphasia Occipital Language, verbal memory and auditory perception Visual loss and visual agnosia</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Broca’s area is the motor speech area and a lesion in this area will result in motor speech impairment. However, this patient’s verbal output is fluent. Option: C. A lesion in the nucleus ambiguus will result in dysarthria and also loss of fluent verbal output. Option: D. The red nucleus is a mesencephalic motor nucleus, which does not participate in the central pathways for speech. Wernicke’s area is the speech comprehension area, which is intact in this patient because he comprehends spoken language</p>\n<p><strong>Extraedge:</strong></p><p>Functional areas of the cerebral cortex Lobe Area Area no Location Representation of body parts Function Effect of lesion Frontal Motor 4 Precentral gyrus and paracentral lobule Upside down except face Controls voluntary activities of the opposite half of the body Contralateral paralysis and Jacksonian fits Premotor 6 Posterior parts of the superior, middle and inferior frontal gyri - Controls extrapyramidal system Often mixed with a pyramidal effect Frontal eye field 6,8 Posterior part of the middle frontal gyrus - Controls horizontal conjugate movements of the eyes Horizontal conjugate movements are lost Motor speech (Broca's area) 44, 45 Pars triangularis and pars opercularis - Controls the spoken speech Aphasia (motor) Prefrontal 9,10,11 12 The remaining large, anterior part of the frontal lobe - Controls emotions, concentration, attention initiative and judgement Loss of orientation Parietal Sensory (somesthetic) 3, 1, 2 Postcentral gyrus and paracentral lobule Upside down except face Perception of exteroceptive (touch, pain and temperature) and proprioceptive impulses Loss of appreciation of the impulses received Sensory association 5,7 Between sensory and visual areas -- Stereognosis and sensory speech Astereognosis and sensory aphasia Wernicke's area 40 Inferior part of parietal lobule -</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 27 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 48-year-old man walks into the clinic with complaints of weight loss. Several biopsies were taken from different parts of the GIT to rule out a diagnosis. Which part is shown in the following histology slide?", "options": [{"label": "A", "text": "Colon", "correct": false}, {"label": "B", "text": "Oesophagus", "correct": true}, {"label": "C", "text": "Stomach", "correct": false}, {"label": "D", "text": "Appendix", "correct": false}], "correct_answer": "B. Oesophagus", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391551461-QTDA035001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Oesophagus Only the Oesophagus and lower part of the anal canal consists of stratified squamous epithelium in the mucosa layer.</p>\n<p><strong>Highyeild:</strong></p><p>Classification of epithelium</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Colon has columnar epithelium with numerous intervening goblet cells. No villi will be seen Option: C . The stomach's Body, Fundus, and Cardiac comprise simple columnar epithelium in the mucosa. Option: D. Usually, the whole appendix is seen in a single slide with no villi. Submucosa has many lymphoid masses.</p>\n<p><strong>Extraedge:</strong></p><p>Histology of esophagus (from inside to outside) Mucous membrane : Epithelial lining is stratified squamous non-keratinized in nature. Lamina propria consists of loose connective tissue with papillae. Muscularis mucosae are distinct in the lower part and formed by longitudinal muscle fibers. Submucosa contains mucus-secreting oesophageal glands. Muscularis externa comprises striated muscle in the upper third, mixed type in the middle third, and smooth muscles in the lower third. Its outer layer includes a longitudinal coat, and the inner layer comprises a circular coat of muscle fibers. Adventitia is the connective tissue with capillaries.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A researcher studying different types of glandular cells present in the GIT obtains the following histology slide from the stomach. Identify the labeled cell.`", "options": [{"label": "A", "text": "Oxyntic Cell", "correct": false}, {"label": "B", "text": "Zymogenic cell", "correct": true}, {"label": "C", "text": "M cells", "correct": false}, {"label": "D", "text": "Pyloric glands", "correct": false}], "correct_answer": "B. Zymogenic cell", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391551866-QTDA035002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Zymogenic cell Short gastric pits help us to identify that this is taken from the fundic part of the stomach. The pyloric part of the stomach contains very deep gastric pits. Gastric pits in the fundus of the stomach contain parietal or oxyntic cells and Chief or zymogenic cells. Option B. Zymogenic or chief cells are basophilic cells present in clusters.</p>\n<p><strong>Highyeild:</strong></p><p>Parietal cells (also known as oxyntic cells) are epithelial cells in the stomach that secrete hydrochloric acid (HCl) and intrinsic factors. These cells are located in the gastric glands found in the lining of the fundus and body regions of the stomach. They contain an extensive secretory network of canaliculi from which the HCl is secreted by active transport into the stomach.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Parietal or oxyntic cells are large eosinophilic cells with central nuclei. Option: C. M cells, which usually aren’t visible in light microscopy, are present in the mucosa lining overlying the gut-associated Lymphoid Tissue and function as antigen-presenting Option: D. Pyloric glands are specialized columnar cells with flat basal nuclei in the gastric pits of the pyloric part of the stomach. They secrete mucus and gastrin hormones.</p>\n<p><strong>Extraedge:</strong></p><p>Salient features of each region of the stomach Cardia Fundus and body Pylorus Presence of cardiac glands (mucous secreting glands) in lamina propria of mucosa. Cardiac glands are either simple tubular, or compound tubulo alveolar Presence of gastric glands in the lamina propria of mucosa. Gastric glands are simple or branched tubular glands. They secrete enzymes and hydrochloric acid Presence of pyloric glands in the lamina propria of mucosa. Pyloric glands (mucous glands) are simple or branched tubular glands that are coiled. Shallow gastric pits Shallow gastric pits occupying superficial 1/4th or less of the mucosa Deep gastric pits occupying 2/3rd of the depth of the mucosa Change of epithelium from stratified squamous of the esophagus to simple columnar epithelium in stomach Epithelium is simple columnar Epithelium is simple columnar. Circular muscle layer is thick and is called as pyloric sphincter</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A researcher collects biopsies from different parts of the GIT. Identify the following histology slide.", "options": [{"label": "A", "text": "Oesophagus", "correct": false}, {"label": "B", "text": "Stomach Fundus", "correct": false}, {"label": "C", "text": "Duodenum", "correct": true}, {"label": "D", "text": "Ileum", "correct": false}], "correct_answer": "C. Duodenum", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391551940-QTDA035003IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Duodenum The given slide shows villi which are absent in the esophagus, stomach, and large intestine. The given slide also shows glandular acini present in the Usually, all intestinal mucous-secreting glands are present in the lamina propria layer of mucosa except in the esophagus and duodenum, where they are present in the submucosa. In the duodenum, these glands are called Brunner’s glands which are mucous-secreting acinus in the submucosa.</p>\n<p><strong>Highyeild:</strong></p><p>Brunner's glands (or duodenal glands) are compound tubular submucosal glands found in that portion of the duodenum above the hepatopancreatic sphincter (i.e., sphincter of Oddi).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Oesophagus has stratified squamous epithelium as mucosa lining. Here it shows simple columnar epithelium. Option: B. Simple columnar epithelium is present in the stomach, but no villi are present in the stomach. Duodenum has broad and closely packed villi. Option: D. Ileum will have more goblet cells and a few thin, finger-shaped villi. Peyer's patches in lamina propria will also be visible, even extending into the submucosa.</p>\n<p><strong>Extraedge:</strong></p><p>The main function of Brunner’s glands is to produce a mucus-rich alkaline secretion, i.e., mucous (containing bicarbonate), to: protect the duodenum from the acidic content of chyme (which is introduced into the duodenum from the stomach); provide an alkaline condition for the intestinal enzymes to be active, thus enabling absorption to take place; lubricate the intestinal walls.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A researcher studies sections of GIT to assess the functions of different types of cells. What is the function of the labeled cell in the following histology slide of the jejunum?", "options": [{"label": "A", "text": "Presents antigens to the lymphoid tissue underneath", "correct": false}, {"label": "B", "text": "Secretes mucus", "correct": false}, {"label": "C", "text": "Contains antimicrobial lysosomal enzymes", "correct": true}, {"label": "D", "text": "Secretes secretin", "correct": false}], "correct_answer": "C. Contains antimicrobial lysosomal enzymes", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391552235-QTDA035004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Contains antimicrobial lysosomal enzymes The question already says that the section is of jejunum. The marked cells present in the crypts of Lieberkuhn are Paneth cells. Paneth cells are specialized pyramidal-shaped epithelial cells containing acidophilic granules near the apex, which contain lysosomal enzymes to digest bacterial walls.</p>\n<p><strong>Highyeild:</strong></p><p>Paneth cells are highly specialized secretory epithelial cells located in the small intestinal crypts of Lieberkühn. The dense granules produced by Paneth cells contain an abundance of antimicrobial peptides and immunomodulating proteins that regulate the composition of the intestinal flora.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. M cells present antigens to the GALT tissue underneath. They are present in the mucosa lining overlying the Option: B. mucus is secreted by goblet cells which appear vacuolar Option: D . Secretin is secreted by S cells in the duodenum and jejunum. They are visible when stained with ammonium silver nitrate.</p>\n<p><strong>Extraedge:</strong></p><p>Paneth cells are cells in the small intestine epithelium, alongside goblet cells, enterocytes, and enteroendocrine cells. Some can also be found in the cecum and appendix. They are below the intestinal stem cells in the intestinal glands (also called crypts of Lieberkühn) and the large eosinophilic refractile granules that occupy most of their cytoplasm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A pathology resident received an unlabelled sample from the operating room. Identify the histology slide given below:", "options": [{"label": "A", "text": "Appendix", "correct": false}, {"label": "B", "text": "Ileum", "correct": true}, {"label": "C", "text": "Colon", "correct": false}, {"label": "D", "text": "Stomach Fundus", "correct": false}], "correct_answer": "B. Ileum", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391552346-QTDA035005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ileum Note the thin finger-shaped villi and the Peyer’s patches seen in the Ileum sections. Peyer's patches in the lamina propria are so big that they even extend into the submucosa.</p>\n<p><strong>Highyeild:</strong></p><p>Histology of Ileum Mucosa: Simple columnar epithelium; also contains Peyer's patches Submucosa: Contains neurovasculature Tunica muscularis: Circular and longitudinal muscle layers Tunica serosa: Simple squamous epithelium</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Usually, the whole appendix is seen in a single slide, with no villi. Submucosa has many lymphoid masses. Option: C . Colon has columnar epithelium with numerous intervening goblet cells. No villi will be seen. Option: D. Body, Fundus, and Cardia part of the stomach consists of simple columnar epithelium in the mucosa. No villi will be seen.</p>\n<p><strong>Extraedge:</strong></p><p>In terms of histology , the mucosa of the ileum consists of simple columnar epithelium consisting of enterocytes and goblet cells . A characteristic histological feature of the ileum is Peyer's patches.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 28-year-old man comes to the emergency department with an alleged history of consumption of 30 tablets of acetaminophen. Which zone of the liver acinus will be the first to get affected?", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": true}, {"label": "D", "text": "Both A and B", "correct": false}], "correct_answer": "C. C", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391552662-QTDA035006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C The functional unit of the liver is the liver acinus.</p>\n<p><strong>Highyeild:</strong></p><p>The liver consists of the following major histological components: Parenchyma, which is represented by hepatocytes Stroma, which is a continuation of the surrounding capsule of Glisson. It consists of connective tissue and contains the vessels. The capsule is also covered by a layer of mesothelium arising from the peritoneum covering the liver. The connective tissue of the stroma is type III collagen (reticulin), which forms a meshwork that provides integrity for the hepatocytes and sinusoids. Sinusoids, which are capillaries traveling between hepatocytes Spaces of Disse (perisinusoidal spaces) are located between the hepatocytes and the sinusoids.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option: B & C . Blood flows from the portal triad into the sinusoids and the central vein. Hence, zone 1 is the first to get affected by toxic insults to the liver. Option: A. Zone 3 is the first to get affected by ischaemic changes.</p>\n<p><strong>Extraedge:</strong></p><p>Hepatic (classic) lobule The classic lobule is the traditional description you have most likely heard of. It consists of hexagonal plates of hepatocytes stacked on top of each other. Within each plate, the hepatocytes radiate outwards from a central vein. As they extend towards the periphery, the hepatocytes are arranged into strips, similar to the spokes of a cartwheel. Hepatic sinusoids travel between the strips of hepatocytes, draining into the central vein.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 40-year-old male patient presents to the clinic with features of left heart failure. Which zone of the liver acinus will be the first affected by ischaemic changes?", "options": [{"label": "A", "text": "A", "correct": true}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "Both B and C", "correct": false}], "correct_answer": "A. A", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391552755-QTDA035007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A The functional unit of the liver is the liver acinus.</p>\n<p><strong>Highyeild:</strong></p><p>Portal lobule While the classic lobule view focuses on the blood supply and hepatic mass arrangement, the portal lobule view underlines the exocrine function of the liver, e., bile secretion. In this case, each functional unit is a triangle, having a central axis through a portal field and imaginary vertices through the three different but closest portal canals surrounding it. The area covered by the triangle represents the hepatic regions that secrete bile into the same bile duct .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A . Zone 3 is the first to get affected by ischaemic changes as it is farthest from the portal triad. Option B&C. Blood flows from the portal triad into the sinusoids and then into the central vein. Hence, zone 1 is the first to get affected by toxic insults to the liver.</p>\n<p><strong>Extraedge:</strong></p><p>Liver acinus The focus of this description is the perfusion, metabolism, and pathology of hepatocytes, providing a more accurate description of the physiology of the liver. A liver acinus functional unit is in the shape of an oval. The short axis is represented by a shared border between two adjacent lobules and the portal canals. The long axis is an imaginary line between two adjacent central veins. Each half of the liver acinus can be divided into three zones: Zone 1 is the one closest to the short axis, hence to the portal canals and supply of arterial blood. The hepatocytes in zone 1 receive the highest amount of oxygen. Zone 2 - It is the one located between zones 1 and 3 Zone 3 is the one furthest from the short axis but closest to the central vein. Hence the hepatocytes receive the least amount of oxygen.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The buccinator muscle is pierced by:", "options": [{"label": "A", "text": "Facial Nerve", "correct": false}, {"label": "B", "text": "Wharton’s duct", "correct": false}, {"label": "C", "text": "Parotid duct", "correct": true}, {"label": "D", "text": "Trigeminal nerve", "correct": false}], "correct_answer": "C. Parotid duct", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Parotid duct At the anterior border of the masseter, the parotid duct turns medially and pierces: The buccal pad of fat The buccopharyngeal fascia The buccinator (obliquely) Mucous membrane</p>\n<p><strong>Highyeild:</strong></p><p>Structure pierced by Buccinator muscle</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Facial Nerve, Option B. Wharton’s duct and Option D. Trigeminal nerves all are incorrect answers because the parotid duct pierces the buccinator muscle.</p>\n<p><strong>Extraedge:</strong></p><p>A parotid abscess is best drained by horizontal incision/making many small holes known as Hilton’s method below the angle of the mandible.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 32-year-old woman asks you what is the soft, thin ridge of tissue that she can feel running forward across the masseter muscle toward her upper lip. You reassure her that it is perfectly normal. Which of the following is the most likely structure she is feeling?", "options": [{"label": "A", "text": "Facial Artery", "correct": false}, {"label": "B", "text": "Maxillary artery", "correct": false}, {"label": "C", "text": "Parotid duct", "correct": true}, {"label": "D", "text": "Facial vein", "correct": false}], "correct_answer": "C. Parotid duct", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Parotid duct The parotid duct, also known as the Stensen’s duct, crosses the masseter muscle transversely and extends to the oral cavity where it opens by the upper second molar. The Parotid duct runs forwards and slightly downwards on the masseter muscle</p>\n<p><strong>Highyeild:</strong></p><p>The parotid duct leaves the anterior edge of the parotid gland midway between the zygomatic arch and the corner of the mouth. It crosses the face in a transverse direction and, after crossing the medial border of the masseter muscle, turns deeply into the buccal fat pad and pierces the buccinator muscle. It opens into the oral cavity near the second upper molar tooth.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. The facial artery can be palpated in the groove anterior to the mandibular angle. Option B. All of the other vessels are located more deeply and cannot be palpated. Option D. The facial vein lies anterior to the artery, passing toward the angle of the lips, but does not ascend close to the masseter.</p>\n<p><strong>Extraedge:</strong></p><p>Parotid gland stones It is not uncommon for stones to develop within the parotid gland. They typically occur within the main confluence of the ducts and the main parotid duct. The patient usually complains of intense pain when salivating and tends to avoid foods that produce this symptom. The pain can be easily reproduced in the clinic by squirting lemon juice into the patient's mouth. Surgery depends upon where the stone is. If it is within the anterior aspect of the duct, a simple incision in the buccal mucosa with a sphincterotomy may allow removal. If the stone is farther back within the main duct, complete gland excision may be necessary.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following statements are true regarding the parotid gland except?", "options": [{"label": "A", "text": "Accessory parotid gland is above the parotid duct", "correct": false}, {"label": "B", "text": "Mandible ramus grooves anteromedial surface", "correct": false}, {"label": "C", "text": "Styloid and mastoid muscles are posteromedially", "correct": false}, {"label": "D", "text": "Pharynx examination is unnecessary", "correct": true}], "correct_answer": "D. Pharynx examination is unnecessary", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pharynx examination is unnecessary The pharyngeal muscles receive innervation from the vagus and glossopharyngeal nerve to work in synchronization to propel food from the oral cavity into the esophagus The preganglionic fibres innervating the parotid gland begin in the inferior salivatory nucleus; pass through the glossopharyngeal nerve, its tympanic branch, the tympanic plexus and the lesser petrosal nerve; and relay in the otic ganglion. The postganglionic fibres pass through the auriculo- temporal nerve and reach the gland. It is important to examine the pharynx during the evaluation of parotid gland disease.</p>\n<p><strong>Highyeild:</strong></p><p>The facial nerve [VII] exits the skull through the stylomastoid foramen and then passes into the parotid gland, where it usually divides into upper and lower trunks. These pass through the substance of the parotid gland, where there may be further branching and anastomosing of the nerves. Five terminal groups of branches of the facial nerve [VII]-the temporal, zygomatic, buccal, marginal mandibular, and cervical branches emerge from the upper, anterior, and lower borders of the parotid gland. Facial nerve emerging out from the anterior border of the Parotid gland</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Accessory parotid gland is above the parotid duct The parotid is the largest of the salivary glands. It weighs about 15 g. It is situated below the external acoustic meatus, between the ramus of the mandible and the sternocleidomastoid. The gland overlaps these structures. Anteriorly, the gland also overlaps the masseter muscle. A part of this forward extension is often detached and is known as the accessory parotid, and it lies between the zygomatic arch and the parotid duct. Option B. Mandible ramus grooves anteromedial surface The anteromedial surface is grooved by the posterior border of the ramus of the mandible. It is related to: a. The masseter b. The lateral surface of the temporomandibular joint. c. The posterior border of the ramus of the mandible d. The medial pterygoid e. The emerging branches of the facial nerve Option C. Styloid and mastoid muscles are posteromedially The posteromedial surface of the parotid gland is moulded to the mastoid and the styloid processes and the structures attached to them.</p>\n<p><strong>Extraedge:</strong></p><p>Tumo u rs of the parotid gland The commonest tumours of the parotid gland are benign and typically involve the superficial gland. These include pleomorphic adenoma and adenolymphoma. Their importance is in relation to their anatomical position. The relationship of any tumour to the branches of the facial nerve [VII] must be defined because resection of the tumour may damage the nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Glossopharyngeal nerve supplies which of the following glands?", "options": [{"label": "A", "text": "Parotid Gland", "correct": true}, {"label": "B", "text": "Submandibular gland", "correct": false}, {"label": "C", "text": "Sublingual gland", "correct": false}, {"label": "D", "text": "Lacrimal gland", "correct": false}], "correct_answer": "A. Parotid Gland", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Parotid Gland All the glands in the face (like the submandibular, sublingual, and lacrimal glands) are supplied by the facial nerve except the parotid gland, which is supplied by the glossopharyngeal nerve. Nerve supply of Parotid gland</p>\n<p><strong>Highyeild:</strong></p><p>Sensory innervation of the parotid gland is provided by the auriculotemporal nerve, which is a branch of the mandibular nerve [V3 ]. This division of the trigeminal nerve exits the skull through the foramen ovale. The auriculotemporal nerve also carries secretomotor fibres to the parotid gland.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options B, C and D are incorrect answers because, All the glands in the face (like submandibular, sublingual, and lacrimal glands) are supplied by the facial nerve except the parotid gland, which is supplied by the glossopharyngeal nerve.</p>\n<p><strong>Extraedge:</strong></p><p>Sympathetic Innervation of the Parotid gland is postganglionic, and vasomotor, and is derived from the plexus around the middle meningeal artery. These fibres start from the lateral horn of the T1 segment of the spinal cord. These synapse in the superior cervical ganglion. Postganglionic fibres travel along branches of the external carotid, and maxillary arteries and their branches.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not supplied by secretomotor fibres of the facial nerve?", "options": [{"label": "A", "text": "Lacrimal Gland", "correct": false}, {"label": "B", "text": "Parotid gland", "correct": true}, {"label": "C", "text": "Submandibular gland", "correct": false}, {"label": "D", "text": "Nasal gland", "correct": false}], "correct_answer": "B. Parotid gland", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Parotid gland The glossopharyngeal nerve carries the secretomotor fibres to the parotid gland.</p>\n<p><strong>Highyeild:</strong></p><p>Parasympathetic innervation of Submandibular and Sublingual gland</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options A & D: The branch's greater petrosal nerve preganglionic fibres continue to the pterygopalatine ganglion, which further supplies the glands like lacrimal, nasal and palatine glands. Option C: The other branch Chorda tympani carries secretomotor fibres to the submandibular ganglion, which further supplies the minor salivary glands (submandibular and sublingual).</p>\n<p><strong>Extraedge:</strong></p><p>Lacrimal gland innervation</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statement about Parotid Gland is incorrect:", "options": [{"label": "A", "text": "Has a duct which opens in the oral cavity opposite the second upper premolar tooth", "correct": true}, {"label": "B", "text": "Lies deep to skin innervated by the great auricular nerve", "correct": false}, {"label": "C", "text": "Receives autonomic nerve Fibers via the otic ganglion", "correct": false}, {"label": "D", "text": "Is almost entirely a serous gland.", "correct": false}], "correct_answer": "A. Has a duct which opens in the oral cavity opposite the second upper premolar tooth", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Has a duct which opens in the oral cavity opposite the second upper premolar tooth The parotid duct leaves the anterior edge of the parotid gland midway between the zygomatic arch and the corner of the mouth. It crosses the face in a transverse direction and, after crossing the medial border of the masseter muscle, turns deeply into the buccal fat pad and pierces the buccinator muscle. It opens into the oral cavity near the second upper molar tooth. Parotid duct opening</p>\n<p><strong>Highyeild:</strong></p><p>The submandibular duct (Wharton’s duct), opens into the oral cavity on the summit of a sublingual papilla at the side of the frenulum of the tongue.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B: Lies deep into the skin innervated by the greater auricular nerve. Option C: The parasympathetic Fibers pass through the glossopharyngeal nerve -- otic ganglion – parotid gland. Option D: Parotid gland is a serous salivary gland. The parotid duct runs over the masseter, turns at right angles, pierces the buccal pad of fat, and buccinators & opens in the vestibule of the mouth opposite to the crown of the upper second molar tooth.</p>\n<p><strong>Extraedge:</strong></p><p>The lymphatics from the submandibular gland first drain into submandibular lymph nodes and subsequently into jugulodigastric lymph nodes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Postganglionic secretomotor fibres to parotid gland is related to :", "options": [{"label": "A", "text": "Ciliary Ganglion", "correct": false}, {"label": "B", "text": "Pterygopalatine ganglion", "correct": false}, {"label": "C", "text": "Otic ganglion", "correct": true}, {"label": "D", "text": "Submandibular ganglion", "correct": false}], "correct_answer": "C. Otic ganglion", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Otic ganglion Sensory innervation of the parotid gland is provided by the auriculotemporal nerve, which is a branch of the mandibular nerve [V3 ]. This division of the trigeminal nerve exits the skull through the foramen ovale. The auriculotemporal nerve also carries secretomotor fibres to the parotid gland. Nerve Supply 1 Parasympathetic nerves are secretomotor. They reach the gland through the auriculotemporal nerve. The preganglionic fibres begin in the inferior salivatory nucleus; pass through the glossopharyngeal nerve, its tympanic branch, the tympanic plexus and the lesser petrosal nerve; and relay in the otic ganglion. The postganglionic fibres pass through the auriculotemporal nerve and reach the gland. This is shown in the Flow chart</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Ciliary Ganglion Option Pterygopalatine ganglion Option Submandibular ganglion Postganglionic secretomotor fibres to the parotid gland are related to the otic ganglion, so Options A, B and D are incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>The submandibular ganglion is a parasympathetic peripheral ganglion. It is a relay station for secretomotor fibres to the submandibular and sublingual salivary glands. Topographically, it is related to the lingual nerve, but functionally, it is connected to the chorda tympani branch of the facial nerve</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 29-year-old woman underwent a thyroidectomy. Postoperatively, the patient presented with hoarseness. Which of the following nerves was most likely injured during the operation?", "options": [{"label": "A", "text": "Internal Laryngeal", "correct": false}, {"label": "B", "text": "External laryngeal", "correct": false}, {"label": "C", "text": "Recurrent laryngeal", "correct": true}, {"label": "D", "text": "Superior laryngeal", "correct": false}], "correct_answer": "C. Recurrent laryngeal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Recurrent laryngeal The recurrent laryngeal nerve supplies most of the motor innervation to the larynx and sensation below the true vocal folds. The thyroid gland and the recurrent laryngeal nerve are in close proximity and thus the nerve is the most likely to be injured with a thyroidectomy Injury to the recurrent laryngeal nerve can result in speech defects, including hoarseness Nerve supply of Thyroid gland</p>\n<p><strong>Highyeild:</strong></p><p>The thyroid gland is closely related to the recurrent laryngeal nerves. After branching from the vagus nerve [X] and looping around the subclavian artery on the right and the arch of the aorta on the left, the recurrent laryngeal nerves ascend in a groove between the trachea and esophagus. They pass deep to the posteromedial surface of the lateral lobes of the thyroid gland and enter the larynx by passing deep to the lower margin of the inferior constrictor of the pharynx.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A,B,D - The superior laryngeal nerve has two branches: the internal laryngeal nerve innervates the mucous membranes of the larynx above the vocal folds, and the external laryngeal nerve innervates the cricothyroid muscle, which tenses the vocal folds.</p>\n<p><strong>Extraedge:</strong></p><p>Together with branches of the inferior thyroid arteries, the recurrent laryngeal nerves are related to and may pass through ligaments, one on each side, that bind the thyroid gland to the trachea and the cricoid cartilage of the larynx. These relationships need to be considered when surgically removing or manipulating the thyroid gland.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 34-year-old woman is admitted to the hospital with a large mass in her thyroid gland. Ultrasound examination suggests a benign tumour, which is confirmed with a biopsy. Twenty-four hours following a partial thyroidectomy, in which the inferior thyroid artery was also ligated, the patient speaks with a hoarse voice and has difficulty in breathing on exertion. Which of the following nerves was most likely injured during the surgical procedure?", "options": [{"label": "A", "text": "Internal branch of the superior laryngeal", "correct": false}, {"label": "B", "text": "Ansa cervicalis", "correct": false}, {"label": "C", "text": "Ansa subclavia", "correct": false}, {"label": "D", "text": "Recurrent laryngeal", "correct": true}], "correct_answer": "D. Recurrent laryngeal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Recurrent laryngeal The recurrent laryngeal nerve is the most likely nerve damaged during the surgery because it runs in close proximity to the inferior thyroid artery and is easily injured or transected with the artery if extreme care is not exercised during operative procedures. The recurrent laryngeal nerve innervates the majority of the vocal muscles that open and close the rima glottidis, in addition to providing sensory supply to the larynx below the vocal folds. Even relatively mild trauma to the nerve can result in hoarseness.</p>\n<p><strong>Highyeild:</strong></p><p>Inferior thyroid artery : It is a branch of the thyrocervical trunk from the first part of the subclavian artery. It first runs upwards along the medial border of the scalenus anterior and then passes medially behind the carotid sheath to reach the back of the thyroid lobe, where it is intimately related to the recurrent laryngeal nerve . The recurrent laryngeal nerve presents a variable relationship with the artery. It may pass behind or in front of the loop of the artery or between the branches of the artery. Arterial and nerve relationship with respect to the thyroid gland</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A - The internal branch of the superior laryngeal nerve is not in close proximity to the inferior thyroid artery and pierces the thyrohyoid membrane to enter the pharynx. Option: B, C - The ansa Subclavia lies lateral to the site of surgery and does not innervate any structures that, if paralyzed, would cause hoarseness. Ansa cervicalis is located on an anterior wall of the carotid sheath.</p>\n<p><strong>Extraedge:</strong></p><p>Superior thyroid artery : It is a branch of the external carotid artery. It runs downwards and forwards in company with the external laryngeal nerve , which it leaves near the upper pole of the thyroid lobe. At the apex of the lobe, it divides into anterior and posterior branches. The anterior branch first descends along the anterior border of the lobe and then continues along the upper border of the isthmus to anastomose with its fellows on the opposite side. The posterior branch descends along the posterior border of the lobe to anastomose with the ascending branch of the inferior thyroid artery. The superior thyroid artery supplies the upper one-third of the lobe and the upper half of the isthmus</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 46-year-old woman is admitted to the hospital with a large mass in her lower anterior neck. Ultrasound examination suggests a benign tumour of her thyroid gland, which is confirmed with a biopsy. During the procedure to remove the tumour, the superior thyroid artery is identified and used as a landmark in order not to damage its small companion nerve. Which of the following nerves is most likely to accompany the superior thyroid artery?", "options": [{"label": "A", "text": "Cervical Sympathetic Trunk", "correct": false}, {"label": "B", "text": "External branch of the superior laryngeal", "correct": true}, {"label": "C", "text": "Inferior root of the ansa cervicalis", "correct": false}, {"label": "D", "text": "Internal branch of the superior laryngeal", "correct": false}], "correct_answer": "B. External branch of the superior laryngeal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>External branch of the superior laryngeal The external branch of the superior laryngeal nerve courses together with the superior thyroid artery for much of its route.</p>\n<p><strong>Highyeild:</strong></p><p>Thyroidea ima artery (is present in 30% of cases): It is a branch of the brachiocephalic trunk or may arise directly from the arch of the aorta. It enters the isthmus from below.</p>\n<p><strong>Extraedge:</strong></p><p>The thyroid gland is supplied by both sympathetic and parasympathetic nerve fibres: The parasympathetic supply is derived from the vagus and recurrent laryngeal nerves. The sympathetic supply is derived from the superior, middle, and inferior cervical sympathetic ganglia, but mainly from the middle one.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 55-year-old woman visits the outpatient clinic with swelling in her neck. Ultrasound examinations reveal a thyroid gland tumour. Three days after thyroidectomy air bubbles are seen on the CT of her brain. Which of the following is the most likely cause of the air bubbles?", "options": [{"label": "A", "text": "Injury to inferior thyroid artery", "correct": false}, {"label": "B", "text": "Injury to superior, middle, and inferior thyroid veins", "correct": false}, {"label": "C", "text": "Injury to superior thyroid artery and vein", "correct": false}, {"label": "D", "text": "Injury to superior and middle thyroid veins", "correct": true}], "correct_answer": "D. Injury to superior and middle thyroid veins", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Injury to superior and middle thyroid veins The superior and middle thyroid veins can be torn in thyroid surgery, perhaps admitting an air bubble (due to negative pressure in the veins) that can ascend in the internal jugular vein into the skull, with deleterious or lethal results.</p>\n<p><strong>Highyeild:</strong></p><p>The venous blood from the thyroid gland is drained by three set s of veins : Superior thyroid vein: It emerges at the upper pole of the thyroid lobe, runs upwards and laterally, and drains into the internal jugular vein. Middle thyroid vein: This short, wide venous channel emerges at the middle of the lobe to soon enter the internal jugular vein. Inferior thyroid vein/veins: They emerge at the lower border of the isthmus, form plexus in front of the trachea and then run downwards to drain into the left brachiocephalic vein. Sometimes a fourth vein, the thyroid vein (of Kocher) emerges between the middle and inferior thyroid veins to drain into the internal jugular vein. Venous drainage of the Thyroid gland</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B - The middle thyroid vein is typically a short, direct tributary to the internal jugular vein. Option: C - The superior thyroid vein is a tributary to the internal jugular vein; it accompanies the superior thyroid artery. Option: D - The inferior thyroid vein usually drains vertically downward to one or both brachiocephalic veins.</p>\n<p><strong>Extraedge:</strong></p><p>The lymph vessels draining the thyroid gland are arranged into two groups, upper and lower, and they follow the arteries: The upper group drains into the prelaryngeal (lying in front of the larynx) and upper deep cervical (jugulodigastric) lymph nodes. The lower group drains into pretracheal and lower deep cervical lymph nodes and a group of lymph nodes along the recurrent laryngeal nerves. Those from the lower part of the isthmus drain into retrosternal or brachiocephalic nodes lying in the superior mediastinum. The upper lymphatics follow the superior thyroid arteries and lower lymphatics follow the inferior thyroid arteries.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 12-year-old girl is brought to the physician by her parents because of a sore neck for 4 days. Her temperature is 37.7° C (99.9° F). Physical examination shows a tender swelling anterior to, and just above, the thyroid notch of the neck. The physician explains that there is a cyst in the tract along which the thyroid gland descended. All of the tract tissue must be removed between which of the following two structures to treat this patient’s condition?", "options": [{"label": "A", "text": "Left lobe of the thyroid gland and tonsillar fossa", "correct": false}, {"label": "B", "text": "Right lobe of the thyroid gland and epiglottis", "correct": false}, {"label": "C", "text": "Right lobe of the thyroid gland and hyoid bone", "correct": false}, {"label": "D", "text": "Thyroid isthmus and foramen cecum", "correct": true}], "correct_answer": "D. Thyroid isthmus and foramen cecum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thyroid isthmus and foramen cecum The thyroid gland develops as an outpouching from the floor of the primitive pharynx. It is temporarily connected to the tongue at the foramen cecum by the thyroglossal duct, which then degenerates. It descends in the neck passing anterior to the hyoid bone. Incomplete degeneration of the thyroglossal duct can lead to a cystic mass in the path of the descent of the thyroid gland. Thyroid gland</p>\n<p><strong>Highyeild:</strong></p><p>During Thyroidectomy, the superior thyroid artery is ligated near the gland to save the external laryngeal nerve. The stem of the inferior thyroid artery is not ligated. Its glandular branches are ligated separately. In this way, the blood supply to parathyroid glands is maintained.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A - The path of thyroid descent doesn't extend between Left lobe of thyroid gland and tonsillar fossa. Option:B- The path of thyroid descent doesn't extend between Right lobe of thyroid gland and epiglottis Option: C - The path of thyroid descent doesn't extend between Right lobe of thyroid gland and hyoid bone</p>\n<p><strong>Extraedge:</strong></p><p>The Thyroid gland lies against vertebrae C5–C7 and T1, embracing the upper part of the trachea. Each lobe extends from the middle of the thyroid cartilage to the fourth or fifth tracheal ring. The isthmus extends from the second to the fourth tracheal ring.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 15 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "In walking, gravity tends to tilt the pelvis and trunk to the unsupported side, major factor in preventing unwanted movements:", "options": [{"label": "A", "text": "Adductor Muscles", "correct": false}, {"label": "B", "text": "Quadriceps", "correct": false}, {"label": "C", "text": "Gluteus maximus", "correct": false}, {"label": "D", "text": "Gluteus medius and minimus", "correct": true}], "correct_answer": "D. Gluteus medius and minimus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Gluteus medius and minimus Gluteus medius and minimus prevent the tilting of pelvis on the unsupported side Gluteus medius and minimus supplied by superior gluteal nerves. Trendelenburg's sign occurs in people with weak or paralyzed hip abductor muscles (gluteus medius gluteus minimus) . The sign is demonstrated by asking the patient to stand on one limb. The pelvis severely drops over the swinging limb when the patient stands on the affected limb. Positive signs are typically found in patients with damage to the superior gluteal nerve . Damage to this nerve may occur with associated pelvic fractures, with space-occupying lesions within the pelvis extending into the greater sciatic foramen, and in some cases relating to hip surgery during which there has been disruption of and subsequent atrophy of the insertion of the gluteus medius gluteus minimus tendons on the greater trochanter. In patients with a positive Trendelenburg's sign, gait is abnormal. Typically during the stance phase of the affected limb, the weakened abductor muscles allow the pelvis to tilt inferiorly over the swing limb. The patient compensates for the pelvic drop by lurching the trunk to the affected side to maintain the level of the pelvis throughout the gait cycle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Pes anserinus includes the following three muscles except:", "options": [{"label": "A", "text": "Semitendinosus", "correct": false}, {"label": "B", "text": "Semimembranosus", "correct": true}, {"label": "C", "text": "Gracilis", "correct": false}, {"label": "D", "text": "Sartorius", "correct": false}], "correct_answer": "B. Semimembranosus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Semimembranosus Tendons of one muscle from each of the three compartments of the thigh: sartorius (anterior), gracilis (medial), and semitendinosus (posterior) are inserted into the upper part of the medial surface of the tibia The anserine bursa is at their tibial attachment separating each other near their insertion and also from the tibial collateral ligament .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Muscle attached to the lateral surface of greater trochanter:", "options": [{"label": "A", "text": "Gluteus Maximus", "correct": false}, {"label": "B", "text": "Gluteus medius", "correct": true}, {"label": "C", "text": "Gluteus minimus", "correct": false}, {"label": "D", "text": "Piriformis", "correct": false}], "correct_answer": "B. Gluteus medius", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Gluteus medius Gluteus medius attaches to the lateral surface of the greater Gluteus minimus attaches to the anterior surface of the greater trochanter. Gluteus Maximus attaches to the posterior aspect of the femur bone at gluteal tuberosity .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Muscle attached to the anterior surface of the greater trochanter:", "options": [{"label": "A", "text": "Gluteus Maximus", "correct": false}, {"label": "B", "text": "Gluteus Medius", "correct": false}, {"label": "C", "text": "Gluteus Minimus", "correct": true}, {"label": "D", "text": "Piriformis", "correct": false}], "correct_answer": "C. Gluteus Minimus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Gluteus Minimus The Gluteus minimus is most anterior in attachment, and the gluteus maximus is most posterior. Insertion of Gluteus maximus is gluteal tuberosity(¼), iliotibial tract(¾) Insertion of Gluteus medius is greater trochanter of the femur( lateral surface) Insertion of Gluteus minimus is greater trochanter of the femur ( anterior surface) The insertion of the Piriformis is the apex of the greater trochanter of the femur.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 14 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The myelogram also revealed that the dorsal and ventral rootlets of the 5th and 6th cervical nerves had been avulsed (torn or pulled out) from the spinal cord on the right side. Which nerve fibres would not be damaged by the avulsion?", "options": [{"label": "A", "text": "General Somatic Afferent", "correct": false}, {"label": "B", "text": "Preganglionic sympathetic", "correct": false}, {"label": "C", "text": "Postganglionic sympathetic", "correct": false}, {"label": "D", "text": "Both b & c", "correct": true}], "correct_answer": "D. Both b & c", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Both b & c Preganglionic (presynaptic) sympathetic neurons originate from the lateral horn of the spinal cord between the levels of T1 and L2. They exit the spinal cord through the ventral rootlets and eventually synapse at the sympathetic ganglia. Since they travel through the ventral rootlets, the preganglionic sympathetic neurons would be damaged by the avulsion of ventral rootlets between T1 and L2, but not in the cervical regions. The postganglionic sympathetic fibres would not be disrupted by avulsing the dorsal and ventral rootlets in any region. They originated in the sympathetic ganglia which are not a part of the spinal cord.</p>\n<p><strong>Highyeild:</strong></p><p>Functional Components of Each Cranial Nerve Component Function Letter Symbols Afferent Fibers Sensory General somatic afferent General sensations GSA Special somatic afferent Hearing, balance, vision SSA General visceral afferent Viscera GVA Special visceral afferent Smell, taste SVA Efferent Fibers General somatic efferent Somatic striated muscles GSE General visceral efferent Glands and smooth muscles (parasympathetic innervation) GVE Special visceral efferent Branchial arch striated muscles SVE</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Somatic afferent neurons originate from the dorsal root and dorsal rootlets. If dorsal rootlets were avulsed, somatic afferent nerve fibres would be damaged. Somatic efferent neurons originate from the ventral root and ventral rootlets. If ventral rootlets were avulsed, somatic efferent nerve fibres would be damaged.</p>\n<p><strong>Extraedge:</strong></p><p>The olfactory, optic, and vestibulocochlear nerves are entirely sensory. The oculomotor, trochlear, abducens, accessory, and hypoglossal nerves are entirely motor. The trigeminal, facial, glossopharyngeal, and vagus nerves are both sensory and motor nerves.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A neuron with a cell body in the dorsal root ganglia could convey what type of fibres?", "options": [{"label": "A", "text": "Motor to the deep back muscles", "correct": false}, {"label": "B", "text": "Motor to the pectoralis major muscle", "correct": false}, {"label": "C", "text": "Sensory from the skin overlying the trapezius", "correct": true}, {"label": "D", "text": "Sympathetic preganglionic to the suprarenal medulla", "correct": false}], "correct_answer": "C. Sensory from the skin overlying the trapezius", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sensory from the skin overlying the trapezius The dorsal root ganglia is the location of the cell bodies of somatic sensory neurons. Cells from the dorsal root ganglia transmit somatic sensations from areas like the skin to the central nervous system. A neuron with a cell body in the dorsal root ganglia is involved in conveying sensory information from the skin overlying the trapezius. Dorsal root ganglion</p>\n<p><strong>Highyeild:</strong></p><p>Spinal nerves carrying sensory information have a dorsal root ganglion, formed by the collection of unipolar cell bodies. Cranial nerves carrying sensory fibres also have sensory ganglia.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options: A, B. Motor neurons have their cell bodies in the ventral horn of the spinal cord. They leave the spinal nerve through the ventral root, join a spinal nerve, and then divide into the ventral and dorsal primary rami. The dorsal primary rami innervate the deep back muscles, while the ventral primary rami innervate other muscles, including pectoralis major (which is innervated via the brachial plexus) . Options: D. The cell bodies of preganglionic sympathetic fibers are found in the lateral horn of the spinal cord. Finally, visceral afferent sensation is not carried on somatic sensory neurons-- instead, the sensation from the stomach is carried on special visceral afferent nerves which accompany sympathetic nerves.</p>\n<p><strong>Extraedge:</strong></p><p>Sympathetic and parasympathetic nerves have autonomic ganglia, formed by the collection of postsynaptic autonomic cell bodies, located away from the brain and spinal cord.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The denticulate ligament:", "options": [{"label": "A", "text": "Is a modification of pia mater", "correct": true}, {"label": "B", "text": "Is found between all dorsal and ventral roots", "correct": false}, {"label": "C", "text": "Attaches to the dural sac continuously", "correct": false}, {"label": "D", "text": "Has its terminal attachment at S2", "correct": false}], "correct_answer": "A. Is a modification of pia mater", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Is a modification of pia mater The denticulate ligaments are specializations of the pia mater that extend from the lateral surface of the pia, helping to suspend the spinal cord in the subarachnoid space.</p>\n<p><strong>Highyeild:</strong></p><p>Ligamenta denticulata These are two transparent ribbon-like thickened bands of the pia mater (one on each side) extending laterally between posterior and anterior nerve roots from the pia mater covering the cord. The lateral margin of each band presents 21 tooth-like processes which pierce the arachnoid, to be attached to the inner surface of the dura mater between the points of emergence of the spinal nerves.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B . These ligaments form longitudinal shelves that separate the dorsal and ventral rootlets. There are only 21 pairs of denticulations, so they are not found between all dorsal and ventral rootlets. Option: C: These ligaments are not continuously attached to the dural sac; instead, they appear between the dorsal and ventral rootlets. Radicular arteries arise as multiple branches of several vessels (vertebral, posterior intercostal, lumbar, and lateral sacral arteries) and accompany the ventral rootlets to reach the spinal cord. Option: D: They do not have a special relationship with the denticulate ligaments.</p>\n<p><strong>Extraedge:</strong></p><p>Differences between spinal and cranial dura Spinal dura Cranial dura Single layered and consists of meningeal layer only Double layered and consists of an inner meningeal layer and outer endosteal layer Does not form folds Forms folds, viz. falx cerebri, falx cerebelli, tentorium cerebelli and diaphragma sellae Epidural space present Epidural space absent</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "As the spinal needle in the above question is being inserted, which ligament would it pass through on its way to the subarachnoid space?", "options": [{"label": "A", "text": "Anterior Longitudinal", "correct": false}, {"label": "B", "text": "Denticulate", "correct": false}, {"label": "C", "text": "Posterior longitudinal", "correct": false}, {"label": "D", "text": "Supraspinous", "correct": true}], "correct_answer": "D. Supraspinous", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Supraspinous To insert a needle into the subarachnoid space, the needle must pass through three ligaments: the supraspinous ligament, interspinous ligament, and ligamenta flava.</p>\n<p><strong>Highyeild:</strong></p><p>The lumbar puncture needle will pass through the following anatomical structures before it enters the subarachnoid space: (a) skin, (b) superficial fascia, (c) supraspinous ligament, (d) interspinous ligament, (e) ligamentum flavum (f) areolar tissue containing the internal vertebral venous plexus, (g) dura mater, and (h) arachnoid mater. The depth to which the needle will have to pass will vary from 1 inch (2.5 cm) or less in a child to as much as 4 inches (10 cm) in an obese adult. Lumbar puncture</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The anterior longitudinal ligament is located along the anterior surfaces of all vertebral bodies, it lies directly posterior to the thoracic and abdominal viscera. Option: B. The denticulate ligaments are paired ligaments that separate the dorsal and ventral rootlets. They are not disturbed during a lumbar puncture. Ligamentum nuchae are located at the nape of the neck--not even close to where you would perform a spinal tap. Option: C . The posterior longitudinal ligament is a ligament on the posterior surfaces of the vertebral bodies. Although it is located in the vertebral canal, it is not penetrated by the needle during a spinal tap.</p>\n<p><strong>Extraedge:</strong></p><p>CSF pressure can be measured by attaching a manometer to the needle. When the patient is In the recumbent position, the normal pressure is about 60 to 150 mm of water. The pressure shows oscillations corresponding to the movements of respiration and the arterial pulse.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Because of their structure and interconnections, which veins are especially important in the metastatic spread of cancer?", "options": [{"label": "A", "text": "Basilic", "correct": false}, {"label": "B", "text": "Cephalic", "correct": false}, {"label": "C", "text": "Dorsal scapular", "correct": false}, {"label": "D", "text": "Internal vertebral venous plexus", "correct": true}], "correct_answer": "D. Internal vertebral venous plexus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Internal vertebral venous plexus The veins of the internal vertebral venous plexus are clinically significant because they are valveless and can serve as a route for metastases. Cancerous cells can travel freely in vertebral veins and lodge somewhere else in the body. The other veins all have valves which would direct the flow of blood and stop some of the metastatic spread.</p>\n<p><strong>Highyeild:</strong></p><p>The internal vertebral venous plexuses ( intraspinal veins ) lie within the vertebral canal in the epidural space and receive tributaries from the bones and the spinal cord. They form a closer network than the external plexuses, and, running mainly in a vertical direction, form four longitudinal veins, two in front and two behind; they, therefore, may be divided into anterior and posterior groups.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A, B, C : are not related to the vertebral plexus</p>\n<p><strong>Extraedge:</strong></p><p>The anterior and posterior plexuses communicate freely with one another by a series of venous rings (retia venosa vertebrarum), one opposite each vertebra. Around the foramen magnum, they form an intricate network which opens into the vertebral veins and is connected above with the occipital sinus, the basilar plexus, the condyloid emissary vein, and the rete canalis hypoglossi. The Batson venous plexus, which communicates the posterior intercostal vessels with the vertebral plexus, lacks valves so blood can flow in both directions. The clinical importance of this venous communication is that it represents an important phase in the establishment of vertebral metastases and neuroschistomiasis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient is suspected of having bacterial meningitis. A lumbar puncture is performed to remove cerebrospinal fluid (CSF) for analysis. If done properly, the needle used for the tap would penetrate all layers except:", "options": [{"label": "A", "text": "Arachnoid Mater", "correct": false}, {"label": "B", "text": "Epidural fat", "correct": false}, {"label": "C", "text": "Dura mater", "correct": false}, {"label": "D", "text": "Pia mater", "correct": true}], "correct_answer": "D. Pia mater", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pia mater The pia mater is the innermost covering of the spinal cord which is closely applied to the entire spinal cord. It does not need to be pierced to retrieve CSF. This fluid is found in the subarachnoid space, outside of the pia mater.</p>\n<p><strong>Highyeild:</strong></p><p>The lumbar puncture needle will pass through the following anatomical structures before it enters the subarachnoid space: (a) skin, (b) superficial fascia, (c) supraspinous ligament, (d) interspinous ligament, (e) ligamentum flavum (f) areolar tissue containing the internal vertebral venous plexus, (g) dura mater, and (h) arachnoid mater. The depth to which the needle will have to pass will vary from 1 inch (2.5 cm) or less in a child to as much as 4 inches (10 cm) in an obese adult.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A, B, C: The needle must pass through the following layers during a lumbar puncture: skin, fat, supraspinous ligament, interspinous ligament, between or through the ligamenta flava, epidural fat and veins, dura, subdural space, and arachnoid.</p>\n<p><strong>Extraedge:</strong></p><p>A lumbar puncture can help diagnose serious infections, such as meningitis; other disorders of the central nervous system, such as Guillain-Barre syndrome and multiple sclerosis; bleeding; or cancers of the brain or spinal cord. Sometimes a lumbar puncture is used to inject anaesthetic medications or chemotherapy drugs into the cerebrospinal fluid.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient is suspected of having bacterial meningitis. A lumbar puncture is performed to remove cerebrospinal fluid (CSF) for analysis. The fluid would be removed from the:", "options": [{"label": "A", "text": "Epidural space at the level of L3", "correct": false}, {"label": "B", "text": "Spinal canal at the level of L 3", "correct": false}, {"label": "C", "text": "Subdural space at the level of L4", "correct": false}, {"label": "D", "text": "Subarachnoid space at the level of L4", "correct": true}], "correct_answer": "D. Subarachnoid space at the level of L4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Subarachnoid space at the level of L4 Lumbar puncture Lumbar puncture is done to withdraw cerebrospinal fluid for various diagnostic and therapeutic purposes. The puncture should be done well below the termination of the cord, i.e. lower border of LI. A horizontal line joining the highest points of the iliac crests passes through the spine of the fourth lumbar vertebra. Therefore, the interspinous spaces immediately above and below this landmark can be used safely. The interspinous space between L3 and L4 is the most preferred site. Because in this region subarachnoid space is more roomy and contains only filum terminale and roots of lumbar, sacral and coccygeal nerves forming the cauda equina.</p>\n<p><strong>Highyeild:</strong></p><p>A lumbar puncture procedure may be helpful in diagnosing many diseases and disorders, including: Meningitis. Encephalitis. Certain cancers involving the brain and spinal cord Bleeding Reye syndrome. Myelitis. Neurosyphilis. Guillain-Barré syndrome. Demyelinating diseases. Headaches of unknown cause. Pseudotumor cerebri Normal pressure hydrocephalus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The epidural space contains epidural fat, and the subdural space is a potential space only. Option: B. Also, remember that a lumbar puncture should be performed at the level of L4. Option: C. Because the spinal cord ends at the bottom of L1 or the top of L2, L4 is a safe level for inserting a needle.</p>\n<p><strong>Extraedge:</strong></p><p>Lumbar puncture may be done to inject medicine directly into the spinal cord. These include: Spinal anaesthetics before a surgical procedure Contrast dye for X-ray studies - for example, myelography Chemotherapy drugs used to treat cancer</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 60-year-old male presented with a number of unusual signs and symptoms in the facial region. Among others, it was found that the right side of his face was flushed (red). Further testing revealed a lack of ability to sweat in the same cutaneous region. Which nervous structures were most likely implicated in this set of clinical abnormalities?", "options": [{"label": "A", "text": "Cranial outflow of the ANS", "correct": false}, {"label": "B", "text": "Dorsal roots of cervical nerves", "correct": false}, {"label": "C", "text": "Gray rami communicantes of T 5", "correct": false}, {"label": "D", "text": "Sympathetic nerve fibres", "correct": true}], "correct_answer": "D. Sympathetic nerve fibres", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sympathetic nerve fibres The sympathetic nerve fibres control the tone of the vasculature and allow for vasoconstriction. If these fibres are damaged, vessels will not be able to vasoconstrict and they will dilate, producing a flush.</p>\n<p><strong>Highyeild:</strong></p><p>Anatomic, Physiologic, and Pharmacologic Characteristics of Sympathetic Versus Parasympathetic Systems Sympathetic Parasympathetic Action Prepares body for emergency Conserves and restores energy Outflow T1-L2 (3) Cranial nerves III, VII, IX, and X; S2-S4 Preganglionic fibers Myelinated Myelinated Ganglia Paravertebral (sympathetic trunks), prevertebral (e.g., celiac, superior mesenteric, inferior mesenteric) Small ganglia close to viscera (e.g., otic, ciliary) or ganglion cells in plexuses (e.g., cardiac, pulmonary) Neurotransmitter within ganglia Acetylcholine Acetylcholine Ganglion-blocking agents Hexamethonium and tetraethylammo- nium by competing with acetylcholine Hexamethonium and tetraethylam- monium by competing with acetylcholine Postganglionic fibers Long, nonmyelinated Short, nonmyelinated Characteristic activity Widespread due to many postganglionic fibers and liberation of epinephrine and norepinephrine from suprarenal medulla Discrete action with few postganglionic fibers Neurotransmitter at postganglionic endings Norepinephrine at most endings and acetylcholine at few endings (sweat glands) Acetylcholine at all endings Blocking agents on receptors of effector cells α -Adrenergic receptors- phenoxybenzamine β-Adrenergic receptors- propranolol Atropine, scopolamine Agents inhibiting synthesis and storage of neurotransmitter at postganglionic endings Reserpine Agents inhibiting hydrolysis of neuro- transmitter at site of effector cells Acetylcholinesterase blockers (e.g., neostigmine) Drugs mimicking autonomic activity Sympathomimetic drugs Phenylephrine α receptors; Isoproterenol: β receptors Parasympathomimetic drugs Pilocarpine Methacholine Higher control Hypothalamus Hypothalamus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The cranial outflow of the autonomic nervous system refers to parasympathetic nervous fibres which do not control the tone of the vasculature. Option: B. Dorsal roots of cervical nerves carry afferent sensory fibres, not sympathetic neurons. Option: C. The gray rami communicans are structures that postganglionic sympathetic neurons travel on before rejoining a spinal nerve, so destroying the gray rami communicans might disrupt the sympathetic outflow.</p>\n<p><strong>Extraedge:</strong></p><p>Autonomic Nervous System Effects on Body Organs Organ Sympathetic Action Parasympathetic Action Eye Pupil Dilates Constricts Ciliary muscle Relaxes Contracts Glands Lacrimal, parotid, submandibular, sublingual, nasal Reduce secretion by causing vasoconstriction of blood vessels Increase secretion Sweat Increases secretion Heart Cardiac muscle Increases force of contraction Decreases force of contraction Coronary arteries (mainly controlled by local metabolic factors) Dilates (ẞ receptors), constricts (a receptors) Lung Bronchial muscle Relaxes (dilates bronchi) Contracts (constricts bronchi) Bronchial secretion Increases secretion Bronchial arteries Constricts Dilates Gastrointestinal tract Muscle in walls Decreases peristalsis Increases peristalsis Muscle in sphincters Contracts Relaxes Glands Reduces secretion by vasoconstriction of blood vessels Increases secretion Liver Breaks down glycogen into glucose Gallbladder Relaxes Contracts Kidney Decreases output due to constriction of arteries Urinary bladder Bladder wall (detrusor) Relaxes Contracts Sphincter vesicae Contracts Relaxes Erectile tissue of penis and clitoris Relaxes, causes erection Ejaculation Contracts smooth muscle of vas deferens, seminal vesicles, and prostate Systemic arteries Skin Constrict Abdominal Constrict Muscle Constrict (a receptors), dilate (ẞ receptors), dilate (cholinergic) rector pili muscle Contract prarenal Cortex Stimulates Medulla Liberates epinephrine and norepinephrine</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which structure does NOT contain efferent autonomic nerve fibres?", "options": [{"label": "A", "text": "Ventral ramus of T2", "correct": false}, {"label": "B", "text": "Dorsal root of T6", "correct": true}, {"label": "C", "text": "Ventral root of T3", "correct": false}, {"label": "D", "text": "Ventral ramus of L2", "correct": false}], "correct_answer": "B. Dorsal root of T6", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Dorsal root of T6 The dorsal root of a spinal nerve contains afferent sensory nerve fibres and no efferent autonomic nerve fibres. The efferent autonomic nerve fibres, which originate in the lateral horn of the spinal nerve, travel out of the spinal cord through the ventral root of the spinal nerve. As the ventral and dorsal roots join to form the spinal nerve, the fibres from both roots intermingle, and the dorsal and ventral primary rami take a mix of fibres, including afferent sensory fibres from the dorsal root, and efferent motor fibres from the ventral root. Postganglionic Sympathetic efferent fibres join each spinal nerve via a gray ramus Communicans. Efferent Pathways of the Autonomic Nervous System The efferent pathways of the ANS consist of 2 neurons that transmit impulses from the CNS to the effector tissue. The preganglionic neuron originates in the CNS with its cell body in the lateral horn of the grey matter of the spinal cord or the brainstem. The axon of this neuron travels to an autonomic ganglion located outside the CNS, where it synapses with a postganglionic neuron. This neuron innervates the effector tissue.</p>\n<p><strong>Highyeild:</strong></p><p>Distinguishing Features of the Sympathetic and Parasympathetic Systems Sympathetic System Parasympathetic Systems Originates in thoracic and lumbar regions of the spinal cord (T1-L2) Originates in brainstem (cranial nerves III, VII, IX, and X) and sacral region of spinal cord (S2-S4) Ganglia located in paravertebral sympathetic ganglion chain or collateral ganglia Terminal ganglia located near or embedded within target tissue Short cholinergic preganglionic fibers; long adrenergic postganglionic fibers Long cholinergic preganglionic fibers; short cholinergic postganglionic fibers Ratio of preganglionic fibers to postganglionic fibers is 1:20 Ratio of preganglionic fibers to postganglionic fibers is 1:3 Divergence coordinates activity of neurons at multiple levels of spinal cord Limited divergence Activity often involves mass discharge of the entire system Activity normally to discrete organs Primary neurotransmitter of postganglionic neurons is norepinephrine Primary neurotransmitter of postganglionic neurons is acetylcholine Predominates during emergency \"fight-or-flight\" reactions and exercise Predominates during quiet resting conditions</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options: A, C, and D : So, all of the other nerves listed do contain efferent autonomic fibres.</p>\n<p><strong>Extraedge:</strong></p><p>The Sympathetic Ganglia are located either in the paravertebral sympathetic trunks or In the prevertebral ganglia, such as the celiac ganglion. The parasympathetic ganglion cells are located as small ganglia close to the viscera or within plexuses within the viscera.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were shown the following specimen during your final professional examination. You were asked about the various modifications of the pia mater. One of the points in the answer included linea splendens. Which of the following statements is true?", "options": [{"label": "A", "text": "It is present on the posterior side of the given structure.", "correct": false}, {"label": "B", "text": "It is present in the anterior median fissure and gives a glistening appearance.", "correct": true}, {"label": "C", "text": "It marks the anteroposterior landmark for the surgical hemisectioning of the cord.", "correct": false}, {"label": "D", "text": "It is present circumferentially throughout the spinal cord.", "correct": false}], "correct_answer": "B. It is present in the anterior median fissure and gives a glistening appearance.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>It is present in the anterior median fissure and gives a glistening appearance. linea splendens is a modification of the pia mater in the spinal cord which is present in the anterior median fissure. Hence, the correct statement is option B.</p>\n<p><strong>Highyeild:</strong></p><p>Ligamenta denticulata is 21 pairs of teeth-like projections. They fuse laterally with the arachnoid and duramater midway between the exits of the roots of adjacent spinal nerves. The highest process attaches immediately superior to the foramen magnum. The ligamentum denticulatum keeps the spinal cord in position.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. It is present on the posterior side of the given structure is a wrong statement. Option: C. It marks the anteroposterior landmark for the surgical hemi-sectioning of the cord, which denotes ligamentum denticulatum. Option: D. It is present circumferentially throughout the spinal cord is a wrong statement.</p>\n<p><strong>Extraedge:</strong></p><p>The spinal cord extends in the lower part of 1st lumbar vertebra as conus medullaris. Below the level of conus medullaris, only the pia mater is continued as a thin fibrous cord, the filum terminale.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were studying internal features of the spinal cord during your 1st year. You came across the term ‘ substantia gelatinosa’. Which of the following tract relay on this?", "options": [{"label": "A", "text": "Dorsal Column", "correct": false}, {"label": "B", "text": "Spinothalamic tract", "correct": true}, {"label": "C", "text": "Spinocerebellar tract.", "correct": false}, {"label": "D", "text": "None of the above.", "correct": false}], "correct_answer": "B. Spinothalamic tract", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spinothalamic tract In the internal features of the spinal cord, there is various nucleus present where the sensory tract relay on the spinal cord. Spinothalamic tract relay in substantia gelatinosa and then form spinal lemniscus.</p>\n<p><strong>Highyeild:</strong></p><p>Substantia gelatinosa: This is found at the tip of the posterior horn through the entire extent of the spinal cord. Here first-order neurons of lateral spinothalamic tract synapse.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Dorsal column tract- the nucleus for this tract to relay is the nucleus proprius. Option: C. spinocerebellar tract- the nucleus for this tract is nucleus dorsalis.</p>\n<p><strong>Extraedge:</strong></p><p>Level of vertebral levels and spinal segments Vertebral levels Spinal segments C1-C7 C1–C8 T1-T6 T1-T8 T7-T9 T9-T12 T10-T11 L1-L5 T12-L1 S1-S5 and Co1</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following nuclei located in the ventral horn have tracts relay for the midline muscles?", "options": [{"label": "A", "text": "Intermedio-Lateral Nuclei.", "correct": false}, {"label": "B", "text": "Intermedio-medial nuclei.", "correct": false}, {"label": "C", "text": "Medial nuclei.", "correct": true}, {"label": "D", "text": "Intermediate nuclei.", "correct": false}], "correct_answer": "C. Medial nuclei.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Medial nuclei. The medial nuclei in the ventral horn of the spinal cord are responsible for the tracts related to midline muscles. Medial group nuclei are present throughout the extent of the spinal cord and innervate the axial muscles of the body</p>\n<p><strong>Highyeild:</strong></p><p>The central canal is present throughout the spinal cord. Superiorly, it is continuous with the central canal of the caudal half of the medulla oblongata; above this, it opens into the cavity of the fourth ventricle. Inferiorly in the conus medullaris, it expands into the fusiform terminal ventricle and terminates below within the root of the filum terminale. It Is filled with CSF and Is lined with ciliated columnar epithelium, the ependyma</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Intermedio-lateral nuclei are responsible for the sympathetic supply (T1-L2) and are located in the lateral horn. Option: B. Intermedio-lateral nuclei are responsible for the parasympathetic supply (S2, S3, S4) and are located in the lateral horn. Option: D. intermediate nuclei located in the ventral horn and give rise to phrenic nerve (C3-C5) and spinal accessory nerve (C1-C5).</p>\n<p><strong>Extraedge:</strong></p><p>Comparison of Structural Details in Different Regions of the Spinal Cord Region Shape White Matter Gray Matter Anterior Gray Column Posterior Gray Column Lateral Gray Column Cervical Oval Fasciculus cuneatus and fasciculus gracilis present Medial group of cells for neck muscles; central group of cells for accessory nucleus (C1-C5) and phrenic nucleus (C3-C5); lateral group of cells for upper limb muscles Substantia gelatinosa present, continuous with Sp.N. of cranial nerve V at level C2; nucleus proprius present; nucleus dorsalis (Clarke column) absent Absent Thoracic Round Fasciculus cuneatus (T1-T6) and fasciculus gracilis present Medial group of cells for trunk muscles Substantia gelatinosa, nucleus proprius, and visceral afferent nucleus present. Present; gives rise to preganglionic sympathetic fibers Lumbar Round to oval Fasciculus cuneatus absent; fasciculus gracilis present Medial group of cells for lower limb muscles; central group of cells for lumbosacral nerve Substantia gelatinosa, nucleus proprius, nucleus dorsalis (Clarke column) at L1-L4, and visceral afferent nucleus present Present (L1-L2 [3]); gives rise to preganglionic sympathetic fibers Sacral Round Small amount; fasciculus cuneatus absent; fasciculus gracilis present Medial group of cells for lower limb and perineal muscles Substantia gelatinosa and nucleus proprius present Absent; group of cells present at S2-S4, for parasympathetic outflow</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During lumbar puncture in a patient, your junior resident tells you that it is done at L3/L4 level as the spinal cord ends at the lower border of L1. In that space we have filum terminale internum and then after S2 , filum terminale externum is present. What is the content of filum terminale internum?", "options": [{"label": "A", "text": "Arachnoid, Piameter, Dura mater.", "correct": false}, {"label": "B", "text": "Arachnoid and pia mater.", "correct": false}, {"label": "C", "text": "Parameter only", "correct": true}, {"label": "D", "text": "Only spinal cord.", "correct": false}], "correct_answer": "C. Parameter only", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Parameter only Between the level of the lower border of L1 and up to S2 there is filum terminale internum which consists of only pia mater and arachnoid and dura mater surround to form space for CSF fluid from which lumbar puncture sample can be taken. Hence, the correct answer is option C.</p>\n<p><strong>Highyeild:</strong></p><p>Filum terminale It is a delicate, glistening white thread-like structure extending from the tip of conus medullaris to the first coccygeal vertebra (dorsal aspect). The filum terminale is about 20 cm long and mainly composed of non-nervous fibrous tissue (pia), but few nerve fibres (considered to be the rudiments of 2nd, 3rd and 4th coccygeal nerves) are found embedded in its upper part. The central cana of the spinal cord extends into the upper part of the filum terminale for about 5 mm. The filum terminale consists of two parts: (a) filum terminale internum, and (b) filum terminale externum. The filum terminale internum is about 15 cm in length and lies within the dural sac. The filum terminale externum is about 5 cm in length and lies outside the dural sac, i. e. below the level of the second sacral vertebra.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Arachnoid, pia mater and dura mater are all present in filum terminale externum which starts after the level of S2. Option: B. Arachnoid and pia mater both are wrong answers for the given question. Option: D. spinal cord ends at the lower border of the L1 vertebrae.</p>\n<p><strong>Extraedge:</strong></p><p>The spinal cord is roughly cylindrical in shape with an average diameter of about 1.25 cm. However, opposite to the attachments of the nerve roots contributing to the formation of brachial and lumbosacral plexuses, the spinal cord presents definite fusiform swellings called cervical and lumbar enlargements respectively. The cervical enlargement extends from C5 to T1 spinal segments whereas lumbar enlargement extends from L2 to S3 spinal segments.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Given below is the histological section which came in your final practical of anatomy for histology. You have correctly identified it as a spinal cord. The nuclei present in the marked structure are responsible for.", "options": [{"label": "A", "text": "Pain and temperature sensation.", "correct": false}, {"label": "B", "text": "Parasympathetic and sympathetic system", "correct": true}, {"label": "C", "text": "Proprioception", "correct": false}, {"label": "D", "text": "Crude touch and pressure.", "correct": false}], "correct_answer": "B. Parasympathetic and sympathetic system", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392265294-QTDA063014IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Parasympathetic and sympathetic system The marked structure in the spinal cord is the lateral horn which consists of intermedio-lateral and intermedio-medial nuclei. These nuclei are responsible for sympathetic and parasympathetic tracts from the body.</p>\n<p><strong>Highyeild:</strong></p><p>Cell groups in the intermediate (lateral) grey column The cells of the lateral grey column form two nuclei: (a) intermediolateral, and (b) intermediomedial. Intermediolateral nucleus extends from T1 to L2 segments of the cord and gives origin to preganglionic fibres of the sympathetic nervous system (thoracolumbar outflow) which leave the cord along with anterior nerve roots. Intermediomedial nucleus extends from S2 to S4 segments of the cord and gives origin to preganglionic fibres of the parasympathetic nervous system (sacral outflow), which also pass out through the anterior nerve roots of the corresponding sacral nerves.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. pain and temperature tract i.e. spinothalamic tract relay in the dorsal horn in substantia gelatinosa. Option: C. proprioception relay in nucleus proprius. Option: D. crude touch and pressure relay in the anterior spinothalamic tract in substantia gelatinosa.</p>\n<p><strong>Extraedge:</strong></p><p>Summary of the various cell columns/nuclei in different horns (grey columns) of the spinal cord Cell columns/nuclei Extend in the cord Functions Posterior horn I. Substantia gelatinosa Entire cord Relay nucleus for pain and temperature, modification of transmission of sensory input II. Nucleus dorsalis (Clarke's column) C8 to L2 or L3 Gives origin to axons which form posterior spinocerebellar tract III. Nucleus proprius Entire cord Contains intemuncial neurons for spinal reflexes and second order sensory neurons of the ventral spinothalamic tract IV. Visceral afferent nucleus T1 to L2 or L3 and S2 to S4 Relay nucleus for visceral afferent impulses Anterior horn V. Medial motor cell column Entire cord Supplies muscles of the neck and trunk VI. Lateral motor cell column C4 to T1 and L2 to S3 Supplies muscles of the extremities VII. Phrenic nucleus C3 to C5 Motor innervations of the diaphragm VIII. Spinal accessory nucleus C1 to C5 Origin of spinal root of accessory nerve Lateral horn IX. Intermediolateral cell column T1 to L2 or L3 Source of preganglionic sympathetic fibres X. Sacral parasympathetic nucleus S2 to S4 Source of preganglionic parasympathetic fibres</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 24 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The lower lip develops from:", "options": [{"label": "A", "text": "fusion of mandibular process on both sides", "correct": true}, {"label": "B", "text": "fusion of medial nasal process with maxillary process", "correct": false}, {"label": "C", "text": "medial nasal process", "correct": false}, {"label": "D", "text": "none of the above", "correct": false}], "correct_answer": "A. fusion of mandibular process on both sides", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>fusion of mandibular process on both sides The lower lip develops from the fusion of the mandibular process on both sides.</p>\n<p><strong>Highyeild:</strong></p><p>Derivation of the various parts of the face</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. fusion of medial nasal process with maxillary process Fusion of the medial nasal process with the maxillary process forms the upper lip Option C. medial nasal process The medial nasal process forms the tip of the nose, columella, philtrum, and incisive process of the palate. Option D. None of the above The lower lip develops from the fusion of the mandibular process on both sides, so none of the above is incorrect. The lateral nasal process forms the lateral part of the lip and its joining with the maxilla forms the nasolacrimal duct with an NLD groove.</p>\n<p><strong>Extraedge:</strong></p><p>Development of Various Parts of the Face The olfactory pits grow deeper to form nasal cavities. The median nasal process thins out gradually to form a primitive nasal septum. The globular processes of medial nasal pro- cesses fuse to form the philtrum of the upper lip. The two maxillary processes grow medially below developing eyes and fuse with the lateral nasal process to form the lateral part of the upper lip and upper part of the cheek. The two mandibular processes form the lower lip and lower part of the cheek. The surface opening of the stomodeum forms the oral fissure. Lateral angles of the oral fissure are formed by the fusion of maxillary and mandibular processes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Dysmorohic anomaly of face and palate:", "options": [{"label": "A", "text": "Goldenhar Syndrome", "correct": false}, {"label": "B", "text": "Treacher Collin syndrome", "correct": false}, {"label": "C", "text": "Craniofrontonasal syndrome", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above Option A. Goldenhar Syndrome Goldenhar syndrome is characterized by hemifacial microsomia affecting one half of the face, small jaw, malformed/absent ear, and ear tags. Stapedial artery hemorrhage has been found to be the genetic basis by experiments in animals. Option B. Treacher Collin syndrome Mandibulofacial dysostosis also known as treacher Collins syndrome due to the involvement of first and second arch components of the cranial neural crest, is characterized by incomplete orbits, reduced jaw, conductive hearing loss, external and middle ear fistula, and results due to mutations in the TCOF1 gene Option C. Craniofrontonasal syndrome Deletion of the EFNB1 gene leads to craniofrontonasal syndrome. It is characterized by a broad forehead, hypertelorism, central nasal groove, premature fusion of coronal sutures and is occasionally associated with cleft lip, and cleft palate. This dysmorphic anomaly of face and palate can occur due to defective embryonic development. Option D. All of the above All of the syndromes mentioned in options A, B, and C are associated with Dysmorohic anomaly of the face and palate. Hence Option D is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Treacher Collins syndrome (mandibulofacial dysostosis): It is inherited as an autosomal dominant trait, i.e., caused by an autosomal dominant gene. It occurs in about 1/85,000 births. Clinically it presents as : Malar hypoplasia (due to underdevelopment of zygomatic bones) Mandibular hypoplasia Down slanting palpebral fissures Deformed external ears.</p>\n<p><strong>Extraedge:</strong></p><p>First arch syndromes: These syndromes occur due to a lack of migration of neural crest cells into the first pharyngeal arch. Clinically, they present with various facial anomalies called first arch syndromes. The important first arch syndromes are (a) Treacher Collins syndrome, (b) Pierre Robin syndrome, and (c) DiGeorge syndrome.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Muscles of the face and palate develop from all except:", "options": [{"label": "A", "text": "fourth pharyngeal arch", "correct": false}, {"label": "B", "text": "first pharyngeal arch", "correct": false}, {"label": "C", "text": "second pharyngeal arch", "correct": false}, {"label": "D", "text": "third pharyngeal arch", "correct": true}], "correct_answer": "D. third pharyngeal arch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>third pharyngeal arch Third pharyngeal arch gives rise to Stylopharyngeus and it is supplied by the glossopharyngeal nerve.</p>\n<p><strong>Highyeild:</strong></p><p>The only muscle derived from the third arch is the stylopharyngeus. It is supplied by the glossopharyngeal nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Fourth pharyngeal arch All muscles of the palate except tensor veli palatini are derived from a) the fourth pharyngeal arch whereas tensor veli palatini arise from b) the first pharyngeal arch. Option B. First pharyngeal arch All muscles of the palate except tensor veli palatini are derived from a) the fourth pharyngeal arch whereas tensor veli palatini arise from b) the first pharyngeal arch. Option C. Second pharyngeal arch Muscles of facial expression are derived from c) the second pharyngeal arch and hence supplied by the facial nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The muscles derived from the first arch are muscles of mastication (, temporalis, masseter, lateral pterygoid, and medial pterygoid), anterior belly of digastric, mylohyoid, tensor tympani, and tensor palati. All these muscles are supplied by the mandibular nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The palate develops from which of the following structures?", "options": [{"label": "A", "text": "Palatine process of maxilla", "correct": false}, {"label": "B", "text": "The horizontal plate of palatine bone", "correct": false}, {"label": "C", "text": "Medial nasal process", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above Option A. Palatine process of maxilla Premaxilla / primitive palate is formed from c) fusion of the medial nasal process and the remaining part develops from a) the palatine process of the maxilla and b) the horizontal plate of the palatine bone. Option B. horizontal plate of palatine bone Premaxilla / primitive palate is formed from c) fusion of medial nasal process and the remaining part develops from a) the palatine process of the maxilla and b) the horizontal plate of the palatine bone. Option C. medial nasal process Premaxilla / primitive palate is formed from c) fusion of the medial nasal process and the remaining part develops from a) the palatine process of the maxilla and b) the horizontal plate of the palatine bone. Option D. all of the above Premaxilla / primitive palate is formed from c) fusion of the medial nasal process and the remaining part develops from a) the palatine process of the maxilla and b) the horizontal plate of the palatine bone. Most parts of the palate ossifies to form a hard palate while the soft palate is formed by the unossified part of the fused Palatal process. The incisive process of the palate develops from the Medial nasal process. Hence all of the above is the correct answer (option D).</p>\n<p><strong>Extraedge:</strong></p><p>Oblique facial clefts are produced by failure of the maxillary prominence to merge with its corresponding lateral nasal prominence along the line of the nasolacrimal groove. When this occurs, the nasolacrimal duct is usually exposed to the surface.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Soft palate arises from:", "options": [{"label": "A", "text": "Unossified part of fused Palatal process", "correct": true}, {"label": "B", "text": "Medial nasal process", "correct": false}, {"label": "C", "text": "Palatine process of maxilla", "correct": false}, {"label": "D", "text": "The horizontal plate of palatine bone", "correct": false}], "correct_answer": "A. Unossified part of fused Palatal process", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Unossified part of fused Palatal process The soft palate is formed by the unossified part of the fused Palatal process whereas most parts of the palate ossify to form a hard palate. Most parts of the palate ossifies to form a hard palate while the soft palate is formed by the unossified part of the fused Palatal process.</p>\n<p><strong>Highyeild:</strong></p><p>Cleft lip: It commonly occurs in the upper lip. The incidence of cleft lip is 1 in 1000 births and 60–80% of children involved are males. The cleft upper lip presents three varieties. Unilateral Cleft Lip: It occurs due to the failure of fusion of the maxillary process with the medial nasal process of the same side. Bilateral cleft lip: It occurs due to the failure of fusion of maxillary processes with the frontonasal process. Central cleft lip/harelip: It occurs due to failure of development of the philtrum of the upper lip from the frontonasal process. Very rarely the two mandibular processes may fail to fuse in the midline to cause cleft lower lip.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. medial nasal process Premaxilla / primitive palate is formed from b) fusion of the medial nasal process and the remaining part develops from c) the palatine process of the maxilla and d) the horizontal plate of the palatine bone. Option C. Palatine process of maxilla Premaxilla/primitive palate is formed from b) fusion of the medial nasal process and the remaining part develops from c) the palatine process of the maxilla and d) the horizontal plate of the palatine bone. Option D. horizontal plate of palatine bone Premaxilla/primitive palate is formed from b) fusion of the medial nasal process and the remaining part develops from c) the palatine process of the maxilla and d) the horizontal plate of the palatine bone.</p>\n<p><strong>Extraedge:</strong></p><p>Microstomia (small mouth) and macrostomia (large mouth): Lateral angles of the oral fissure are formed at the junction of the maxillary and mandibular processes. Initially, the lateral angle of the mouth extends much laterally close to the auricle. Subsequently in normal conditions, the angles of the mouth gradually shift medially by fusion between the maxillary and mandibular processes till a normal adult position is reached. The excessive fusion of these processes leads to microstomia and the arrest of this fusion leads to macrostomia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are true about mandibulofacial dysostosis except:", "options": [{"label": "A", "text": "Involvement of first and second arch components of cranial neural crest", "correct": false}, {"label": "B", "text": "Characterized by incomplete orbits, reduced jaw, conductive hearing loss, external and middle ear fistula", "correct": false}, {"label": "C", "text": "Due to haploinsufficiency of TCOF1", "correct": false}, {"label": "D", "text": "Deletion of the EFNB1 gene", "correct": true}], "correct_answer": "D. Deletion of the EFNB1 gene", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deletion of the EFNB1 gene Deletion of EFNB1 gene leads to craniofrontonasal syndrome.</p>\n<p><strong>Highyeild:</strong></p><p>Defects in the development of the face can result in: Goldenhar syndrome Treacher Collin syndrome Craniofrontonasal syndrome</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Involvement of first and second arch components of cranial neural crest Mandibulofacial dysostosis is also known as Treacher Collins syndrome and a) involvement of first and second arch components of cranial neural crest, b) characterized by incomplete orbits, reduced jaw, conductive hearing loss, external and middle ear fistula, and c) due to haploinsufficiency of TCOF1. Option B. Characterized by incomplete orbits, reduced jaw, conductive hearing loss, external and middle ear fistula Mandibulofacial dysostosis is also known as Treacher Collins syndrome and a) involvement of first and second arch components of cranial neural crest, b) characterized by incomplete orbits, reduced jaw, conductive hearing loss, external and middle ear fistula, and c) due to haploinsufficiency of TCOF1. Option C. Due to haploinsufficiency of TCOF1 Mandibulofacial dysostosis is also known as Treacher Collins syndrome and a) involvement of first and second arch components of cranial neural crest, b) characterized by incomplete orbits, reduced jaw, conductive hearing loss, external and middle ear fistula, and c) due to haploinsufficiency of TCOF1.</p>\n<p><strong>Extraedge:</strong></p><p>Van der Woude syndrome is the most common syndrome associated with cleft lip with or without cleft palate. The syndrome is inherited as an autosomal dominant and is due to mutations in INTERFERON REGULATORY FACTOR 6 [IRF6; 1p32—41] that is expressed in the medial edge of the palatal shelves. Interestingly, 88% of affected infants will have pits in their lower lip, and in 64% of these individuals, this will be the only abnormality.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Midline cleft upper lip is due to failure of fusion between:", "options": [{"label": "A", "text": "2 Maxillary Processes", "correct": false}, {"label": "B", "text": "2 Medial nasal processes", "correct": true}, {"label": "C", "text": "2 Mandibular process", "correct": false}, {"label": "D", "text": "Medial nasal process and Maxillary process", "correct": false}], "correct_answer": "B. 2 Medial nasal processes", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2 Medial nasal processes Failure of fusion of 2 Medial nasal processes leads to Midline Cleft upper lip.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. 2 Maxillary Processes Cleft palates typically develop from a failure of fusion of the opposing palatine processes of the paired maxillary prominences. Option C. 2 Mandibular process Failure of fusion of two mandibular processes leads to lower lip cleft. Option D. Medial nasal process and Maxillary process Failure of the medial nasal prominences to fuse with the medial aspect of the maxillary process produces a cleft lip, among the most common congenital abnormalities of the head and neck. A complete cleft lip extends into the floor of the nose, whereas an incomplete cleft extends only partway through the upper lip.</p>\n<p><strong>Extraedge:</strong></p><p>Oblique facial cleft (also called orbito-facial fissure): It is a rare congenital anomaly of the face, which occurs when the maxillary process fails to fuse with the lateral nasal process. The fissure extends from the medial angle of the eye to the upper lip. Consequently, the nasolacrimal duct is exposed to the exterior. This anomaly is usually bilateral.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The body of a male child is handed over to the forensic department by the police officers for further investigations. The forensic expert on examination finds a diamond-shaped membrane filled between the two parietal and frontal bones. No other such membranous spaces are found. After a complete examination of the body, he told the police officers the age of the child should be less than 18-24 months but more than 3 months. How do you think the expert predicted the age of the child?", "options": [{"label": "A", "text": "As the expert found an unclosed anterior fontanelle in the child", "correct": true}, {"label": "B", "text": "As the expert found unclosed lambda in the body", "correct": false}, {"label": "C", "text": "Both of the above", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. As the expert found an unclosed anterior fontanelle in the child", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>As the expert found an unclosed anterior fontanelle in the child Bregma is the meeting point of the coronal suture [between frontal and parietal bones] and sagittal suture [between the parietal bones]. In the fetal skull, this is the site of a membranous gap called the anterior fontanelle which closes at 18-24 months of age. It allows the growth of the brain. So as this is present in the body and it is unclosed that clearly indicates the age of the child should be in between 18-24 months.</p>\n<p><strong>Highyeild:</strong></p><p>The bregma is the midline bony landmark where the coronal and sagittal sutures meet, between the frontal and two parietal bones. It is the anterior fontanelle in the neonate and closes in the second year 2 (typically around 18 months after birth). It is one of the skull landmarks, craniometric points for radiological or anthropological skull measurement. Fontanelles of Skull</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Incorrect Lambda is the meeting point between the sagittal suture [between the parietal bones] and lambdoid suture[between occipital and parietal bones] It is the site of the posterior fontanelle which closes at birth - 2-3 months of age. And it is found closed in the body, and only a single membrane-filled space is found which is the anterior fontanelle. Option: C. Incorrect AS option b given above is incorrect so both of the above cannot be the correct option.</p>\n<p><strong>Extraedge:</strong></p><p>The posterior fontanelle usually closes by age 1 or 2 months. It may already be closed at birth.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 19-year-old camper fell asleep with the right side of her face against the cold earth on an autumn night. In the morning, she woke up and found that she could not move the right side of her face. She went to the local emergency room in a nearby town and was diagnosed with Bell’s palsy. Which of the following muscles is not affected by her condition?", "options": [{"label": "A", "text": "Buccinator", "correct": false}, {"label": "B", "text": "Levator Labii Superioris", "correct": false}, {"label": "C", "text": "Levator Labii Superioris Alaeque Nasi", "correct": false}, {"label": "D", "text": "Levator Palpebrae Superioris", "correct": true}], "correct_answer": "D. Levator Palpebrae Superioris", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Levator Palpebrae Superioris The Levator Palpebrae Superioris, which opens the upper eyelid and is located in the orbit, is innervated by the oculomotor (third cranial) nerve. In the case of Bell’s palsy, long-term exposure to the cold has affected the peripheral portion of the facial (seventh cranial) nerve. In the case of ptosis, a frontalis sling is one of the procedures that can be performed in which the frontalis muscle can take the role of the LPS muscle.</p>\n<p><strong>Highyeild:</strong></p><p>The levator palpebrae Superioris originates from the inferior surface of the lesser wing of the sphenoid bone, just above the optic foramen. It broadens and decreases in thickness (becomes thinner) and becomes the levator aponeurosis . This portion inserts on the skin of the upper eyelid, as well as the superior tarsal plate. It is a skeletal muscle. The superior tarsal muscle, a smooth muscle, is attached to the levator palpebrae Superioris, and inserts on the superior tarsal plate as well.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A, B, C. The buccinator (choice A), levator labii superioris (choice B), levator labii superioris alaeque nasi (choice C), and orbicularis oculi) are all innervated by the facial nerve and will all be impaired.</p>\n<p><strong>Extraedge:</strong></p><p>The levator palpebrae Superioris receives motor innervation from the superior division of the oculomotor nerve . The smooth muscle that originates from its undersurface, called the superior tarsal muscle, is innervated by postganglionic sympathetic axons from the superior cervical ganglion. The levator palpebrae superioris elevates the upper eyelid.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Sensory supply to the middle ear is provided by:", "options": [{"label": "A", "text": "Facial Nerve", "correct": false}, {"label": "B", "text": "Glossopharyngeal nerve", "correct": true}, {"label": "C", "text": "Trigeminal nerve", "correct": false}, {"label": "D", "text": "Vagus nerve", "correct": false}], "correct_answer": "B. Glossopharyngeal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Glossopharyngeal nerve Nerve Supply of Middle Ear: The nerve supply is derived from the tympanic plexus which lies over the promontory. The Jacobson’s nerve is a branch of the glossopharyngeal nerve which provides sensory supply to the middle ear.</p>\n<p><strong>Highyeild:</strong></p><p>Tympanic Plexus It is a plexus of nerves on the promontory in the medial wall of the middle ear. It is formed by: Tympanic branch of the glossopharyngeal nerve (Jacobson’s nerve). Superior and inferior caroticotympanic nerves derived from the sympathetic plexus around the internal carotid artery, and Branch from facial ganglion(geniculate ganglion). The tympanic plexus supplies the mucous membrane of the middle ear, mastoid air cells, and bony eustachian tube. The lesser petrosal nerve derived from it contains secretomotor fibers of the glossopharyngeal nerve to supply the parotid gland via otic ganglion.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Facial Nerve Facial nerve: It runs in the bony canal along the medial and posterior walls of the tympanic cavity and gives rise to three branches, Chorda tympani nerve, which (i) carries taste sensations from the anterior two-third of the tongue except for vallate papillae, and (ii) provides secretomotor fibers to submandibular and sublingual salivary glands. Greater petrosal nerve, which provides secretomotor fibers to lacrimal, nasal, and palatal mucous glands. Nerve to the stapedius muscle. Option C. Trigeminal nerve Mandibular nerve: It provides motor fibers to the tensor tympani muscle. Option D. Vagus nerve The auricular branch of the vagus nerve is often termed Alderman's nerve or Arnold's nerve. The auricular branch of the vagus nerve supplies sensory innervation to the skin of the ear canal, tragus, and auricle.</p>\n<p><strong>Extraedge:</strong></p><p>The middle ear is supplied by six arteries, Anterior tympanic branch of the maxillary artery. Stylomastoid branch of the posterior auricular artery. Petrosal branch of the middle meningeal artery, running along the greater petrosal nerve. Superior tympanic branch of the middle meningeal artery, running along the canal for tensor tympani. The branch from the artery of the pterygoid canal. Tympanic branch of the internal carotid artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "What is true about the pharyngotympanic tube?", "options": [{"label": "A", "text": "It opens into the oropharynx", "correct": false}, {"label": "B", "text": "Partly supplied by the glossopharyngeal nerve", "correct": true}, {"label": "C", "text": "The bony part forms the anterior and medial two-thirds of the tube", "correct": false}, {"label": "D", "text": "Arterial supply is derived directly from the Facial artery", "correct": false}], "correct_answer": "B. Partly supplied by the glossopharyngeal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Partly supplied by the glossopharyngeal nerve PHARYNGOTYMPANIC TUBE The auditory tube is also known as the pharyngotympanic tube or the eustachian tube. Nerve Supply Osseous portion supplied by the tympanic plexus The cartilaginous portion is supplied by the pharyngeal branch of the pterygopalatine ganglion and the meningeal branch of the mandibular nerve.</p>\n<p><strong>Highyeild:</strong></p><p>There are four muscles associated with the function of the Eustachian tube: Levator veli palatini (innervated by the vagus nerve) Salpingopharyngeus (innervated by the vagus nerve) Tensor tympani (innervated by the mandibular nerve of CN V) Tensor veli palatini (innervated by the mandibular nerve of CN V) The tube is opened during swallowing by contraction of the tensor veli palatini and levator veli palatini, muscles of the soft palate.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. It opens into the oropharynx The auditory tube opens in the nasopharynx and is guided by the Salpingopalatine muscle and fold. The auditory tube is a trumpet-shaped channel that connects the middle ear cavity with the nasopharynx. Option C. Bony part forms the anterior and medial two-thirds of the tube The tube is divided into bony and cartilaginous parts: The bony part forms the posterior and lateral one-third of the tube. It is 12 mm long and lies in the petrous temporal bone near the tympanic plate. The cartilaginous part forms the anterior and medial two-thirds of the tube. It is 25 mm long and lies in the sulcus tubae, a groove between the greater wing of the sphenoid and the apex of the petrous temporal. It is about 4 cm long and is directed downwards, forwards, and medially. It forms an angle of 45° with the sagittal plane and 30° with the horizontal plane. Option D. Arterial supply is derived from the Facial artery Vascular Supply The arterial supply of the tube is derived from the ascending pharyngeal and middle meningeal arteries (branch of the Maxillary artery) and the artery of the pterygoid canal. The veins drain into the pharyngeal and pterygoid plexus of veins. Lymphatics pass to the retropharyngeal nodes</p>\n<p><strong>Extraedge:</strong></p><p>The mucous membrane of the tube is continuous in front with that of the nasopharynx, and behind with that of the tympanic cavity. It is covered with ciliated epithelium and is thin in the osseous portion, while in the cartilaginous portion, it contains many mucous glands and near the pharyngeal orifice a considerable amount of adenoid tissue.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The roof of the olfactory region is formed by:", "options": [{"label": "A", "text": "Nasal Bone", "correct": false}, {"label": "B", "text": "Cribriform plate of the ethmoid", "correct": true}, {"label": "C", "text": "Sphenoid", "correct": false}, {"label": "D", "text": "Temporal bone", "correct": false}], "correct_answer": "B. Cribriform plate of the ethmoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cribriform plate of the ethmoid The basal surface of olfactory receptor cells is located directly inferior to the cribriform plate of the ethmoid bone which makes up the bony roof of the nasal cavity.</p>\n<p><strong>Highyeild:</strong></p><p>OLFACTORY NERVE—1ST NERVE The olfactory cells (16–20 million in man) are bipolar neurons. They lie in the olfactory part of the nasal mucosa and serve both as receptors as well as the first neurons in the olfactory pathway. The olfactory nerves, about 20 in number, represent the central processes of the olfactory cells. They pass through the cribriform plate of ethmoids and make synaptic glomeruli with cells of the olfactory bulb. Olfactory nerves forming roof of the olfactory region</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Nasal Bone Option C. Sphenoid Option D. Temporal bone Options A, C, and D do not form the roof of the olfactory region.</p>\n<p><strong>Extraedge:</strong></p><p>Olfactory neurons are bipolar neurons and communicate in the olfactory bulb in the brain.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The lockwood ligament is found in:", "options": [{"label": "A", "text": "Orbit", "correct": true}, {"label": "B", "text": "Pharynx", "correct": false}, {"label": "C", "text": "Larynx", "correct": false}, {"label": "D", "text": "TMJ", "correct": false}], "correct_answer": "A. Orbit", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Orbit The lower part of Tenon’s capsule is thickene and is named the suspensory ligament of the eye or the suspensory ligament of Lockwood. It is expanded in the center and narrow at its extremities and is slung like a hammock below the eyeball. It is formed by the union of the margins of the sheaths of the inferior rectus and the inferior oblique muscles with the medial and lateral check ligaments.</p>\n<p><strong>Highyeild:</strong></p><p>Fascial Sheath of Eyeball or Bulbar Fascia - This provides structural framework support to the eye. Tenon’s capsule forms a thin, loose membranous sheath around the eyeball, extending from the optic nerve to the sclerocorneal junction or limbus . It is separated from the sclera by the episcleral space which is traversed by delicate fibrous bands. The eyeball can freely move within this sheath. The Tenon’s sheath is pierced by: Tendons of the various extraocular muscles. Ciliary vessels and nerves around the entrance of the optic nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Pharynx Option C. Larynx Option D. TMJ Options B, C, and D are not associated with the suspensory ligament of Lockwood.</p>\n<p><strong>Extraedge:</strong></p><p>The sheath gives off a number of expansions. A tubular sheath covers each orbital muscle . The medial check ligament is a strong triangular expansion from the sheath of the medial rectus muscle; it is attached to the lacrimal bone . The lateral check ligament is a strong triangular expansion from the sheath of the lateral rectus muscle; it is attached to the zygomatic bone . The lower part of Tenon’s capsule is thickened and is named the suspensory ligament of the eye or the suspensory ligament of Lockwood. It is expanded in the center and narrow at its extremities and is slung like a hammock below the eyeball. It is formed by the union of the margins of the sheaths of the inferior rectus and the inferior oblique muscles with the medial and lateral check ligaments . Suspensory ligament of Lockwood</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 23 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Parafollicular or C cells of the thyroid develop from:", "options": [{"label": "A", "text": "1st Endodermal Pouch", "correct": false}, {"label": "B", "text": "2nd endodermal pouch", "correct": false}, {"label": "C", "text": "3rd endodermal pouch", "correct": false}, {"label": "D", "text": "ultimobranchial body", "correct": true}], "correct_answer": "D. ultimobranchial body", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>ultimobranchial body Ultimobranchial body , a remnant of the fifth pharyngeal pouch gives rise to C cells of the These cells secrete calcitonin which is a tumor marker for medullary carcinoma .</p>\n<p><strong>Highyeild:</strong></p><p>The neural crest cells that migrate into the caudal pharyngeal complex (ultimobranchial body) form parafollicular/C cells of the thyroid gland.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. 1st endodermal pouch gives rise to the inner lining of the tympanic membrane, eustachian tube, mastoid antrum, and lining of the middle ear cavity. Option B . 2nd endodermal pouch gives rise to epithelium covering the palatine tonsil and tonsillar crypts. Option C . 3rd endodermal pouch gives rise to Thymus and inferior parathyroid gland.</p>\n<p><strong>Extraedge:</strong></p><p>Parathyroid III, developing from the third pouch, migrates caudally along with the thymus. Hence, its position is lower than the parathyroid IV developing from the fourth pouch.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Muscles of the middle ear are derived from:", "options": [{"label": "A", "text": "3rd pharyngeal arch", "correct": false}, {"label": "B", "text": "1st and 2nd pharyngeal arch", "correct": true}, {"label": "C", "text": "4th pharyngeal arch", "correct": false}, {"label": "D", "text": "6th pharyngeal arch", "correct": false}], "correct_answer": "B. 1st and 2nd pharyngeal arch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1st and 2nd pharyngeal arch Muscles of the middle ear include tensor tympani from 1st pharyngeal arch and stapedius from 2nd pharyngeal arch.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. 3rd pharyngeal arch gives rise to Stylopharyngeus and it is supplied by the glossopharyngeal nerve. Option C. 4th pharyngeal arch gives rise to cricothyroid, all muscles of palate except tensor veli palatini, muscles of pharynx except with Stylopharyngeus and cricopharyngeus. Option D. 6th pharyngeal arch gives rise to all muscles of the larynx except cricothyroid, cricopharyngeus</p>\n<p><strong>Extraedge:</strong></p><p>The epithelium of the dorsal region of the fourth pharyngeal pouch forms the superior parathyroid gland When the parathyroid gland loses contact with the wall of the pharynx, it attaches itself to the dorsal surface of the caudally migrating thyroid as the superior parathyroid gland.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Artery of third pharyngeal arch:", "options": [{"label": "A", "text": "Maxillary Artery", "correct": false}, {"label": "B", "text": "Arch of the aorta and right subclavian artery", "correct": false}, {"label": "C", "text": "Stapedial and hyoid artery", "correct": false}, {"label": "D", "text": "common carotid artery and internal carotid artery", "correct": true}], "correct_answer": "D. common carotid artery and internal carotid artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Common carotid artery and internal carotid artery Common carotid arteries and internal carotid arteries are arteries of the third pharyngeal arch.</p>\n<p><strong>Highyeild:</strong></p><p>Mesenchyme for the formation of the head region is derived from paraxial and lateral plate me soderm, neural crest, and thickened regions of ectoderm known as ectodermal placodes. Paraxial mesoderm (somites and somitomeres) forms a large portion of the membranous and cartilaginous components of the neurocranium (skull).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Maxillary artery is the artery of the first pharyngeal arch. Option B. Arch of the aorta and right subclavian are arteries of the fourth pharyngeal arch. Option C. Stapedial and hyoid arteries are arteries of the second pharyngeal arch.</p>\n<p><strong>Extraedge:</strong></p><p>Each pharyngeal arch consists of a core of mesenchymal tissue covered on the outside by surface ectoderm and on the inside by epithelium of endodermal origin. In addition to mesenchyme derived from paraxial and lateral plate mesoderm, the core of each arch receives substantial numbers of neural crest cells, which migrate into the arches to contribute to skeletal components of the face. The original mesoderm of the arches gives rise to the musculature of the face and neck.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The lower part of the body of the hyoid is from:", "options": [{"label": "A", "text": "3rd pharyngeal arch", "correct": true}, {"label": "B", "text": "2nd pharyngeal arch", "correct": false}, {"label": "C", "text": "4th pharyngeal arch", "correct": false}, {"label": "D", "text": "6th pharyngeal arch", "correct": false}], "correct_answer": "A. 3rd pharyngeal arch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>3rd pharyngeal arch The lower part of the body of the hyoid along with the greater cornu of the hyoid develops from the third pharyngeal arch Glossopharyngeal nerve is the nerve of 3rd pharyngeal arch.</p>\n<p><strong>Highyeild:</strong></p><p>The cartilage of the second arch (Reichert’s) forms the following: Dorsal end of the cartilage forms -Stapes, Styloid process. Ventral part forms- Smaller (lesser) cornu of the hyoid bone The superior part of the body of the hyoid bone. The part between the ventral and dorsal parts disappears but its perichondrium forms a Stylohyoid ligament (from the sheath).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. 2nd pharyngeal arch gives rise to the lesser cornu and upper part of the body of the hyoid. Option C. 4th pharyngeal arch gives rise to all laryngeal cartilages except the cricothyroid and base of the arytenoid. Option D. 6th pharyngeal arch gives rise to the cricothyroid and base of the arytenoid.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Cricothyroid arises from:", "options": [{"label": "A", "text": "3rd pharyngeal arch", "correct": false}, {"label": "B", "text": "1st pharyngeal arch", "correct": false}, {"label": "C", "text": "4th pharyngeal arch", "correct": true}, {"label": "D", "text": "6th pharyngeal arch", "correct": false}], "correct_answer": "C. 4th pharyngeal arch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4th pharyngeal arch All muscles of the larynx arise from the 6th pharyngeal arch except the cricothyroid which arises from the 4th pharyngeal arch.</p>\n<p><strong>Highyeild:</strong></p><p>The cartilage of the first arch is called Meckel’s cartilage. The incus and malleus (of the middle ear) and spine of the sphenoid are derived from its dorsal end. The ventral part of the cartilage is surrounded by the mesenchyme that forms the mandible by membranous ossification. The Meckel’s cartilage is thus trapped in the developing mandible and is absorbed. The part of the cartilage extending from the region of the middle ear to the mandible disappears, but its sheath (perichondrium) forms the anterior ligament of the malleus and the sphenomandibular ligament. The mesenchyme of the ventral part of the first arch forms the mandible and that of the dorsal part (maxillary part) forms bones of the face including the maxilla, zygomatic bone, palatine bone, and part of the temporal bone by membranous ossification.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A . 3rd pharyngeal arch gives rise to Stylopharyngeus Option B. 1st pharyngeal arch gives rise to tensor tympani, tensor veli palatini, Mylohyoid, anterior belly of digastric, and muscles of mastication. Option C. 4th pharyngeal arch gives rise to cricothyroid, all muscles of palate except tensor veli palatini, muscles of pharynx except with Stylopharyngeus and cricopharyngeus. Cricothyroid muscle is supplied by external laryngeal nerves.</p>\n<p><strong>Extraedge:</strong></p><p>The following structures are formed from the ventral part of the cartilage of the third arch and the dorsal part disappears: Greater cornu of the hyoid bone The lower part of the body of the hyoid bone.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following does the first pharyngeal cleft give rise to?", "options": [{"label": "A", "text": "outer layer of the tympanic membrane", "correct": true}, {"label": "B", "text": "inner layer of tympanic membrane", "correct": false}, {"label": "C", "text": "middle fibrous layer of the tympanic membrane", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. outer layer of the tympanic membrane", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>outer layer of the tympanic membrane The first pharyngeal cleft gives rise to the outer layer of the tympanic membrane.</p>\n<p><strong>Highyeild:</strong></p><p>Derivatives of pharyngeal clefts and pharyngeal membranes Cleft Adult derivatives First External auditory meatus Outer ectodermal layer of tympanic membrane Second Obliterate/disappear Third Fourth Membrane Adult derivatives First Tympanic membrane Second Obliterate/disappear Third Fourth</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. inner layer of the tympanic membrane arises from the first pharyngeal pouch and Option C. middle fibrous layer of the tympanic membrane arises from the first pharyngeal arch. The Tympanic membrane is derived from all 3 germ layers- ectoderm, mesoderm, and endoderm. Option D. None of the above is incorrect.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which one of the following is incorrect?", "options": [{"label": "A", "text": "pharyngeal cleft – ectoderm", "correct": false}, {"label": "B", "text": "pharyngeal arch – mesoderm", "correct": false}, {"label": "C", "text": "pharyngeal pouch - endoderm", "correct": false}, {"label": "D", "text": "pharyngeal cleft - mesoderm", "correct": true}], "correct_answer": "D. pharyngeal cleft - mesoderm", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>pharyngeal cleft - mesoderm The pharyngeal cleft is formed by the Hence option d) is incorrect.</p>\n<p><strong>Highyeild:</strong></p><p>The pharyngeal arches are six-curved mesodermal thickenings with each arch having an ectodermal covering and an endodermal lining containing a mesodermal core. Coronal sections through the cranial part of the foregut. (A) Before, (B) After formation of pharyngeal arches.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. pharyngeal cleft – ectoderm, Option B. pharyngeal arch – mesoderm and Option C. Pharyngeal pouch – endoderm are all correct options Mesoderm of the pharyngeal arch forms respective bones of pharyngeal arches.</p>\n<p><strong>Extraedge:</strong></p><p>The mesoderm of the arches is derived from paraxial mesoderm and lateral plate mesoderm. It is invaded by neural crest cells that contribute to skeletal elements and connective tissue of the head and neck region.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Ligament formed from Reichert's cartilage:", "options": [{"label": "A", "text": "Stylohyoid", "correct": true}, {"label": "B", "text": "Sphenomandibular", "correct": false}, {"label": "C", "text": "Anterior ligament of malleus", "correct": false}, {"label": "D", "text": "Annular ligament", "correct": false}], "correct_answer": "A. Stylohyoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Stylohyoid The stylohyoid ligament arises from the 2nd pharyngeal arch(Reichert’s cartilage). The facial nerve is the nerve of the 2nd pharyngeal arch.</p>\n<p><strong>Highyeild:</strong></p><p>Second Pharyngeal Arch The cartilage of the second or hyoid arch (Reichert cartilage), gives rise to the stapes, styloid process of the temporal bone, stylohyoid ligament, and ventrally, the lesser horn and upper part of the body of the hyoid bone. Mesenchyme of the arch also forms most of the external ear. Muscles of the hyoid arch are the stapedius, stylohyoid, posterior belly of the digastric, auricular, and muscles of facial expression. The facial nerve, the nerve of the second arch, supplies all of these muscles.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Sphenomandibular and Option C. Anterior ligament of malleus arise from 1st pharyngeal arch. Option D. Annular ligament and footplate of stapes are derived from the otic capsule.</p>\n<p><strong>Extraedge:</strong></p><p>Cartilaginous components of the fourth and sixth pharyngeal arches fuse to form the thyroid, cricoid, arytenoid, corniculate, and cuneiform cartilages of the larynx. Muscles of the fourth arch (cricothyroid, Levato veli palatini, and constrictors of the pharynx) are innervated by the superior laryngeal branch of the vagus, the nerve of the fourth arch. Intrinsic muscles of the larynx are supplied by the recurrent laryngeal branch of the vagus, the nerve of the sixth arch.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Persistent cervical sinus causes:", "options": [{"label": "A", "text": "Branchial Cyst", "correct": true}, {"label": "B", "text": "Thyroglossal cyst", "correct": false}, {"label": "C", "text": "Branchial fistula", "correct": false}, {"label": "D", "text": "Cystic hygroma", "correct": false}], "correct_answer": "A. Branchial Cyst", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Branchial Cyst Persistent cervical sinus results in a branchial cyst.</p>\n<p><strong>Highyeild:</strong></p><p>Branchial FistuIa Branchial fistulas occur when the second pharyngeal arch fails to grow caudally over the third and fourth arches, leaving remnants of the second, third, and fourth clefts in contact with the surface by a narrow canal. Such a fistula, found on the lateral aspect of the neck directly anterior to the sternocleidomastoid muscle, usually provides drainage for a lateral cervical cyst. These cysts, remnants of the cervical sinus, are most often just below the angle of the jaw], although they may be found anywhere along the anterior border of the sternocleidomastoid muscle. Frequently, a lateral cervical cyst is not visible at birth but becomes evident as it enlarges during childhood.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Thyroglossal cyst is formed by the persistence of the thyroglossal duct. Option C. Branchial fistula is formed when a branchial cyst gets infected. Option D. Cystic hygroma is due to failure of sequestration of lymphatics Turner’s syndrome can also be associated with cystic hygroma.</p>\n<p><strong>Extraedge:</strong></p><p>Internal branchial fistulas are rare; they occur when the cervical sinus is connected to the lumen of the pharynx by a small canal, which usually opens in the tonsillar region. Such a fistula results from a rupture of the membrane between the second pharyngeal cleft and pouch at some time during development.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Vagus nerve supplies which of the following arches?", "options": [{"label": "A", "text": "1st and 2nd pharyngeal arch", "correct": false}, {"label": "B", "text": "2nd and 3rd pharyngeal arch", "correct": false}, {"label": "C", "text": "3rd and 4th pharyngeal arch", "correct": false}, {"label": "D", "text": "4th and 6th pharyngeal arch", "correct": true}], "correct_answer": "D. 4th and 6th pharyngeal arch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4th and 6th pharyngeal arch The 4th pharyngeal arch is supplied by the superior laryngeal nerve and the 6th pharyngeal arch is supplied by recurrent laryngeal nerves which are branches of the vagus nerve respectively.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. 1st pharyngeal arch is supplied by the mandibular nerve and 2nd pharyngeal arch is by the facial nerve. Option B. 2nd pharyngeal arch is supplied by the facial nerve and 3rd pharyngeal arch is supplied by the glossopharyngeal nerve. Option C . The 3rd pharyngeal arch is supplied by the glossopharyngeal nerve and the 4th pharyngeal arch is supplied by the superior laryngeal nerve. The stylopharyngeus muscle is supplied by the glossopharyngeal nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The pinna (or auricle) is formed from a series of swellings or hillocks that arise on the first and second arches, where they adjoin the first cleft. The ventral part of this cleft is obliterated.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Reema was asked to pick the odd one out by her friend after they studied the topic of pharyngeal arches:", "options": [{"label": "A", "text": "1st Arch", "correct": true}, {"label": "B", "text": "2nd arch", "correct": false}, {"label": "C", "text": "3rd arch", "correct": false}, {"label": "D", "text": "4th arch", "correct": false}], "correct_answer": "A. 1st Arch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1st Arch Reema answered with the first pharyngeal arch because it is the only pharyngeal arch that is lined by ectoderm alone (both inside and outside).</p>\n<p><strong>Highyeild:</strong></p><p>The maxillary artery is the artery of the first pharyngeal arch and the mandibular nerve is the nerve of the 1st arch.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. 2nd arch, Option C. 3rd arch, and Option D. 4th arch are lined by both i.e. endoderm (on inside) and ectoderm (on the outside).</p>\n<p><strong>Extraedge:</strong></p><p>Ectoderm lining both the inner and outer aspect of the first pharyngeal arch as shown in the image. Primitive pharynx (as seen in coronal section) Before the formation of pharyngeal arches. B. After the formation of pharyngeal arches.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are neural crest cells derivatives except:", "options": [{"label": "A", "text": "Parasympathetic Ganglion", "correct": false}, {"label": "B", "text": "Ciliary ganglion", "correct": false}, {"label": "C", "text": "Retina", "correct": true}, {"label": "D", "text": "Melanoblast", "correct": false}], "correct_answer": "C. Retina", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Retina Retina develops from Diencephalon. The retina and optic nerve are extensions of the brain and diencephalon.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A . parasympathetic ganglion, Option B. ciliary ganglion, and Option D. melanoblast develop from neural crest cells.</p>\n<p><strong>Extraedge:</strong></p><p>BMPs, other members of the TGF-B family, and FGFs regulate NCC migration, proliferation, and differentiation, and abnormal concentrations of these proteins have been associated with neural crest defects in the craniofacial region of the animal.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Cranial neuropore closes at:", "options": [{"label": "A", "text": "Day 25", "correct": true}, {"label": "B", "text": "day 29", "correct": false}, {"label": "C", "text": "A & B", "correct": false}, {"label": "D", "text": "none of the above", "correct": false}], "correct_answer": "A. Day 25", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Day 25 The cranial neuropore closes on day 25. The neural tube is initially an open tube but gradually, it closes and results in the formation of the spinal cord.</p>\n<p><strong>Highyeild:</strong></p><p>Caudal ends of the neural tube communicate with the amniotic cavity by way of the anterior (cranial) and posterior (caudal) neuropores, respectively. Closure of the cranial neuropore occurs at approximately day 25 (18- to 20-somite stage), whereas the posterior neuropore closes at day 28 (25-somite stage). Neurulation is then complete, and the central nervous system is represented by a closed tubular structure with a narrow caudal portion, the spinal cord, and a much broader cephalic portion characterized by a number of dilations, the brain vesicles.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Caudal neuropore closes at Day 25. Hence Option B. day 29, Option C. a & b and D. none of the above options are incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>Neural tube defects [NTDs] result when neural tube closure fails to occur. If the neural tube fails to close in the cranial region, then most of the brain fails to form, and the defect is called anencephaly. If closure fails anywhere from the cervical region caudally, then the defect is called spina bifida.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All neuroglial cells are derived from neuroepithelial cells except:", "options": [{"label": "A", "text": "Astrocyte", "correct": false}, {"label": "B", "text": "Oligodendrocyte", "correct": false}, {"label": "C", "text": "Ependymal cells", "correct": false}, {"label": "D", "text": "Microglia", "correct": true}], "correct_answer": "D. Microglia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Microglia Microglial cells are mesenchymal in origin Microglial cells are the most numerous connecting tissue cells in the central nervous system.</p>\n<p><strong>Highyeild:</strong></p><p>Genesis of the nervous system and special sense</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. astrocyte, Option B . oligodendrocyte, and Option C. ependymal cells arise from neuroepithelial cells.</p>\n<p><strong>Extraedge:</strong></p><p>As the neural folds come together and fuse, cells at the tips of neural folds break away from the neuroectoderm to form the neural crest cells. The surface ectoderm of one side becomes continuous with the surface ectoderm of the opposite side over the neural tube.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Adenohypophysis develops from which of the following structures?", "options": [{"label": "A", "text": "Telencephalon", "correct": false}, {"label": "B", "text": "Diencephalon", "correct": false}, {"label": "C", "text": "Metencephalon", "correct": false}, {"label": "D", "text": "Rathke's pouch", "correct": true}], "correct_answer": "D. Rathke's pouch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Rathke's pouch Adenohypophysis arises from Rathke’s pouch and is ectodermal. Craniopharyngioma is also derived from Rathke’s pouch.</p>\n<p><strong>Highyeild:</strong></p><p>The adenohypophysis/anterior pituitary develops from an ectodermal diverticulum that grows upward from the roof of the stomodeum (primitive mouth), just in front of the buccopharyngeal membrane. The diverticulum is called Rathke’s pouch. Subdivisions of the pituitary gland</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Telencephalon forms cerebral hemispheres and corpus striatum. Option B. diencephalon gives rise to the thalamus, hypothalamus, epithalamus, metathalamus, retina, and optic stalk. Option C. Metencephalon forms pons and cerebellum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following genes are involved molecular regulation of brain development except:", "options": [{"label": "A", "text": "LIMI", "correct": false}, {"label": "B", "text": "OTX2", "correct": false}, {"label": "C", "text": "HOX", "correct": false}, {"label": "D", "text": "SHH", "correct": true}], "correct_answer": "D. SHH", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>SHH SHH regulates the formation of the motor plate of the spinal cord .</p>\n<p><strong>Highyeild:</strong></p><p>Dorsal (sensory) and ventral (motor) regions of the developing spinal cord are dependent upon concentration gradients between members of the transforming growth factor B (TGF-B) family of growth factors secreted in the dorsal neural tube and sonic hedgehog (SHH) secreted by the notochord and floor plate.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. LIMI Option B. OTX2 and Option C. HOX regulate development of the forebrain, midbrain, and hindbrain respectively. Defects in these genes during embryonic development can result in defective neural development.</p>\n<p><strong>Extraedge:</strong></p><p>At the neural plate stage, LIM1, expressed in the prechordal plate, and OTX2, expressed in the neural plate, are important for designating the forebrain and midbrain areas, with LIMI supporting OTX2 expression SHH, secreted by the prechordal plate, induces expression of NKX2.1, a homeodomain-containing gene that regulates the development of the hypothalamus. The Hox genes are central to events involved in specifying the hindbrain territory.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are true about Arnold Chiari malformation except.", "options": [{"label": "A", "text": "A condition in which brain tissue extends into the spinal cord", "correct": false}, {"label": "B", "text": "It occurs when part of the skull is abnormally small or deformed, pressing on the brain and forcing it downwards", "correct": false}, {"label": "C", "text": "Chiari malformation type I develops as the skull and brain are growing. As a result, signs and symptoms may not occur until late childhood or adulthood.", "correct": false}, {"label": "D", "text": "Chiari malformation type II and type I, are present at birth", "correct": true}], "correct_answer": "D. Chiari malformation type II and type I, are present at birth", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Chiari malformation type II and type I, are present at birth Chiari malformation type II and type III are present at birth. The pediatric forms, Chiari malformation type 2 and type 3, are present at birth (congenital). Treatment of Chiari malformation depends on the form, severity, and associated symptoms. Regular monitoring, medications, and surgery are treatment options. In some cases, no treatment is needed.</p>\n<p><strong>Highyeild:</strong></p><p>Chiari malformations Types Chiari Malformation Description Type I Occurs when the cerebellar tonsils extend into the foramen magnum Usually first noticed in adolescence or adulthood Asymptomatic adolescents and adults may develop signs of the disorder later in life Type II Symptoms are generally more severe than in type I and usually appear during childhood Both the cerebellum and brain stem tissue protrude into the foramen magnum Usually accompanied by a myelomeningocele, resulting in partial or complete paralysis of the area below the spinal opening Term Amold-Chiari malformation is specific to type Il malformations Type III Rarest and most serious form Some of the cerebellum and the brain stem herniate through an abnormal opening in the back of the skull Appears in infancy and can cause debilitating and life-threatening complications Infants with type III can have many of the same symptoms as those with type II but can also have additional severe neurologic defects such as mental delays, physical delays, and seizures Type IV Involves an incomplete or underdeveloped cerebellum (cerebellar hypoplasia) In this rare form, the cerebellum is located in its normal position but parts of it are missing, and portions of the skull and spinal cord may be visible</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option C. Chiari malformation type I develops as the skull and brain are growing. As a result, signs and symptoms may not occur until late childhood or adulthood. Arnold Chiari’s malformation is due to Option A . a condition in which brain tissue extends into the spinal cord and Option B. It occurs when part of the skull is abnormally small or deformed, pressing on the brain and forcing it downwards. All of the above are seen in cases of Chiari malformation.</p>\n<p><strong>Extraedge:</strong></p><p>Dandy-Walker syndrome: It occurs due to atresia and blockage of apertures in the roof of the fourth ventricle (e.g., foramen of Magendie and foramina of Luschka). This syndrome consists of dilatation of the fourth ventricle, agenesis of the cerebellar vermis, occipital meningocele, and often agenesis of the splenium of the corpus callosum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Cerebral aqueduct of Sylvius develops from:", "options": [{"label": "A", "text": "Cavity of Telencephalon", "correct": false}, {"label": "B", "text": "cavity of the diencephalon", "correct": false}, {"label": "C", "text": "cavity of the mesencephalon", "correct": true}, {"label": "D", "text": "cavity of Metencephalon", "correct": false}], "correct_answer": "C. cavity of the mesencephalon", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>cavity of the mesencephalon The cerebral aqueduct of the sylvius develops from the cavity of the The cerebral aqueduct of the sylvius connects 3rd ventricle to 4th ventricle.</p>\n<p><strong>Highyeild:</strong></p><p>Stages in the differentiation of brain vesicles and ventricular system</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. lateral ventricle arises from the cavity of the telencephalon Option B. third ventricle arises from the cavity of the diencephalon Option D. fourth ventricle arises from the cavity of the Metencephalon</p>\n<p><strong>Extraedge:</strong></p><p>Hydrocephalus is characterized by an abnormal accumulation of CSF within the ventricular system. In most cases, hydrocephalus in the newborn is due to an obstruction of the aqueduct of Sylvius [aqueductal stenosis]. This prevents the CSF of the lateral and third ventricles from passing into the fourth ventricle and from there into the subarachnoid space, where it would be resorbed. As a result, fluid accumulates in the lateral ventricles and presses on the brain and bones of the skull. Because the cranial sutures have not yet fused, spaces between them widen as the head expands. In extreme cases, brain tissue and bones become thin and the head may be very large.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which is the structure of diencephalic down growth?", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": true}], "correct_answer": "D. D", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682684879-QTDA083023IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>D D - Pars nervosa neurohypophysis is a diencephalic down growth connected with the hypothalamus. ADH and oxytocin are delivered axonally to the neurohypophysis.</p>\n<p><strong>Highyeild:</strong></p><p>The pituitary gland consists of two distinct parts: (a) adenohypophysis ( anterior pituitary ) and (b) neurohypophysis ( posterior pituitary ). Adenohypophysis develops from an evagination of the ectoderm lining the roof of a primitive oral cavity called Rathke’s pouch . The Rathke’s pouch develops in the third week of intrauterine life (IUL). Later the Rathke’s pouch is cut off from the primitive mouth or stomodeum. The anterior wall of Rathke’s pouch proliferates extensively to form pars anterior ( anterior lobe ) of the hypophysis cerebri. The posterior wall of Rathke’s pouch remains thin and forms pars intermedia . The cleft of Rathke’s pouch persists as a hypophyseal cleft, which separates the two parts. A small extension of pars anterior grows upward along the infundibular stalk and eventually surrounds it to form pars tuberalis . Neurohypophysis develops from an evagination of the neurectoderm of the hypothalamus/floor of the third ventricle. The neurohypophysis differentiates into two parts: pars posterior (posterior lobe/pars nervosa) and stalk of the hypophysis (infundibulum). Stages of development of the pituitary gland.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A- Pars Tuberalis Option B - Pars Intermedia Option C - Pars Distalis A, B, and C are parts of anterior pituitary adenohypophysis which is an ectodermal derivative of the stomodeum.</p>\n<p><strong>Extraedge:</strong></p><p>Subdivisions of hypophysis cerebri</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 29 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Epithelium of the tongue is derived from all pharyngeal arches except?", "options": [{"label": "A", "text": "1st Arch", "correct": false}, {"label": "B", "text": "2nd arch", "correct": true}, {"label": "C", "text": "3rd arch", "correct": false}, {"label": "D", "text": "4th arch", "correct": false}], "correct_answer": "B. 2nd arch", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2nd arch 1st arch gives rise to the epithelium of the anterior 2/3rd of the tongue. 3rd arch and 4th arch together form hypobranchial eminence giving rise to epithelium of the posterior 1/3rd and posterior-most parts of the tongue. Hence 2nd arch does not contribute to the development of the epithelium of the tongue.</p>\n<p><strong>Highyeild:</strong></p><p>Development of various parts of the tongue from different sources. Five sources of development. B. Definitive tongue</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. 1st arch gives rise to epithelium of anterior 2/3rd of tongue Option C . 3rd arch and J Option D. 4th arch together form hypobranchial eminence giving rise to epithelium of posterior 1/3rd and posterior-most parts of the tongue.</p>\n<p><strong>Extraedge:</strong></p><p>Taste sensations from the anterior two-third of the tongue are carried by the lingual nerve, from the posterior one-third by the glossopharyngeal nerve, and from the posterior most part by the internal laryngeal nerve. The beer is tasted at the posterior most part of the tongue which is supplied by the internal laryngeal nerve. For this reason, the internal laryngeal nerve is also called the ‘beer drinker’s nerve.’</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The lens is derived from?", "options": [{"label": "A", "text": "Mesoderm", "correct": false}, {"label": "B", "text": "Surface ectoderm", "correct": true}, {"label": "C", "text": "Neuroectoderm", "correct": false}, {"label": "D", "text": "Neural crest cells", "correct": false}], "correct_answer": "B. Surface ectoderm", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Surface ectoderm Surface ectoderm derivatives- lens, corneal, conjunctival epithelium, lacrimal, and tarsal glands.</p>\n<p><strong>Highyeild:</strong></p><p>The surface ectoderm (or external ectoderm) forms the following structures: Skin (only epidermis; dermis is derived from mesoderm) (along with glands, hair, and nails) Epithelium of the mouth and nasal cavity and glands of the mouth and nasal cavity Tooth enamel (as a side note, dentin, and dental pulp are formed from ectomesenchyme which is derived from ectoderm (specifically neural crest cells and travels with mesenchymal cells) Epithelium of anterior pituitary Lens, cornea, lacrimal gland, tarsal glands, and the conjunctiva of the eye Apical ectodermal ridge inducing the development of the limb buds of the embryo. Sensory receptors in the epidermis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Mesoderm derivatives- extraocular muscles, sclera, choroid, and stroma of ciliary body Option C. Neuroectoderm derivatives-retina, optic nerve, optic tract, optic chiasma, pupillary muscles, ciliary body epithelium. Option D. Neural crest cell derivatives. The neural crest is a transient embryonic structure in vertebrates that gives rise to most of the peripheral nervous system (PNS) and to several non-neural cell types, including smooth muscle cells of the cardiovascular system, pigment cells in the skin, and craniofacial bones, cartilage, and connective tissue .</p>\n<p><strong>Extraedge:</strong></p><p>table,tr,th,td {border:1px solid black;} Sensory neurons Cholinergic neurons Adrenergic neurons Rohon-Beard cells Schwann cells Glial cells Chromaffin cells Parafollicular cells Calcitonin producing cells Melanocytes Chondroblasts, chondrocytes Osteoblasts, osteocytes Odontoblasts Fibroblasts Cardiac mesenchyme Striated myoblasts Spinal ganglia Thyroid gland Ultimobranchial body Adrenal gland Teeth Dentine Connective tissue Adipose tissue Smooth muscles Cardiac septa Dermis Cornea Endothelia Adipocytes Mesenchymal cells Smooth myoblasts</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following structures are involved in the formation of the tongue except:", "options": [{"label": "A", "text": "Lingual Swelling", "correct": false}, {"label": "B", "text": "Tuberculum impar", "correct": false}, {"label": "C", "text": "Hypobranchial eminence", "correct": false}, {"label": "D", "text": "Thyroglossal duct", "correct": true}], "correct_answer": "D. Thyroglossal duct", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thyroglossal duct The thyroglossal duct helps in the descent of the thyroid during its development to reach its anatomical position. Ectopic thyroid can be a remnant of the thyroid gland anywhere along the path of the thyroglossal duct.</p>\n<p><strong>Highyeild:</strong></p><p>The oral part of the tongue develops from three swellings associated with the first pharyngeal arch. These swellings are two lateral lingual swellings and one median swelling— the tuberculum impar. The pharyngeal part of the tongue develops from a median swelling called hypobranchial eminence or copula of His associated with second, third, and fourth pharyngeal arches. Muscles of the tongue develop from occipital myotomes.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Lingual swelling and Option B. Tuberculum impar together forms epithelium of anterior 2/3rd of tongue Option C. Hypobranchial eminence cranial part gives rise to epithelium of circumvallate papillae and posterior 1/3 rd of tongue and caudal part gives rise to epithelium of posterior most part of the tongue.</p>\n<p><strong>Extraedge:</strong></p><p>The muscles of the tongue develop from myoblasts that migrate into the developing tongue from the occipital myotomes . The hypoglossal nerve —the nerve of occipital myotomes—accompanies the myoblasts during their migration to the pharyngeal arches and innervates the muscles of the tongue as they develop. The migration of the occipital myotomes to the developing tongue explains the course of the hypoglossal nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Sphincter pupillae is derived from:", "options": [{"label": "A", "text": "Surface Ectoderm", "correct": false}, {"label": "B", "text": "Neuroectoderm", "correct": true}, {"label": "C", "text": "Mesoderm", "correct": false}, {"label": "D", "text": "Neural crest cells", "correct": false}], "correct_answer": "B. Neuroectoderm", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Neuroectoderm Neuroectoderm derivatives-retina, optic nerve, optic tract, optic chiasma, pupillary muscles, ciliary body epithelium. Sphincter pupillae muscle help in causing miosis.</p>\n<p><strong>Highyeild:</strong></p><p>The neuroectodermal cells of the optic cup give rise to muscles of the iris (sphincter and dilator pupillae). The two layers of the epithelium of the iris constitute the iridial part of the retina. The vascular connective tissue of the iris is derived from the mesoderm located anterior to the optic cup.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. surface ectoderm derivatives-lens, corneal epithelium, conjunctival epithelium, lacrimal and tarsal glands Option C . Mesoderm derivatives- extraocular muscles, sclera, choroid, and stroma of the ciliary body. Option D . Neural crest cells The neural crest is a transient embryonic structure in vertebrates that gives rise to most of the peripheral nervous system (PNS) and to several non-neural cell types, including smooth muscle cells of the cardiovascular system, pigment cells in the skin, and craniofacial bones, cartilage, and connective tissue .</p>\n<p><strong>Extraedge:</strong></p><p>The cornea is derived from the following sources: Outer stratified squamous epithelium is derived from the surface ectoderm. Lamina propria of the cornea is derived from the mesoderm. It is continuous with the sclera. The inner corneal epithelium is derived from the neural crest cells.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Epithelium derived from the caudal part of hypobranchial eminence:", "options": [{"label": "A", "text": "Epiglottis", "correct": true}, {"label": "B", "text": "Circumvallate papillae", "correct": false}, {"label": "C", "text": "posterior 1/3 rd of tongue", "correct": false}, {"label": "D", "text": "anterior 2/3 rd", "correct": false}], "correct_answer": "A. Epiglottis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Epiglottis Epiglottis is derived from the caudal part of hypobranchial eminence.</p>\n<p><strong>Highyeild:</strong></p><p>The posterior-most part of the tongue and epiglottis develop from the caudal part of the hypobranchial eminence. Since the mucous membrane of the posterior-most part of the tongue and epiglottis develop from the fourth pharyngeal arch, it is supplied by the superior laryngeal nerve—the nerve of the fourth arch.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Circumvallate papillae and Option C. Posterior 1/3 rd of the tongue are derived from the Cranial part of hypobranchial eminence. Option D . The anterior 2/3rd from lingual swelling, tuberculum impar. Anterior 2/3rd of the tongue has a general sensory supply from the lingual nerve whereas the taste sensation is from the Chorda tympani nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The line of fusion of the anterior two-third and posterior one-third of the tongue is indicated by a V-shaped groove—the Sulcus terminalis . Since the mucous membrane of the posterior one-third of the tongue (including vallate papillae) develops from the third pharyngeal arch, it is supplied by the glossopharyngeal nerve —the nerve of the third arch.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The gene responsible for differentiation of neuroepithelium into neural retina:", "options": [{"label": "A", "text": "CHX10", "correct": true}, {"label": "B", "text": "MITF", "correct": false}, {"label": "C", "text": "Both A & B", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. CHX10", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>CHX10 CHX10 is responsible for neural retinal differentiation of neuroepithelium.</p>\n<p><strong>Highyeild:</strong></p><p>Fibroblast growth factors (FGFs) from the surface ectoderm promote differentiation of the neural (inner layer) retina, whereas transforming growth factor B (TGF-B), secreted by surrounding mesenchyme, directs the formation of the pigmented (outer) retinal layer. Downstream from these gene products, the t ranscription factors MITF and CHX1O are expressed and direct dif ferentiation of the pigmented and neural layer, respectively.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. CHX10 is responsible for neural retinal differentiation of neuroepithelium. Option B. MITF is responsible for pigment epithelium differentiation of neuroepithelium Hence c) & d) cannot be the answer to the above question Any defect in these genes during embryonic development can result in abnormal development of the retina and vision problems in children.</p>\n<p><strong>Extraedge:</strong></p><p>PAX6 is the key regulatory gene for eye development.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Genes involved in the differentiation of retinal neuroepithelium are all except:", "options": [{"label": "A", "text": "CHX10", "correct": false}, {"label": "B", "text": "MITF", "correct": false}, {"label": "C", "text": "PAX 6", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. PAX 6", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>PAX 6 PAX 6 is involved in the formation of optic vesicles. Optic cup and lens development require Pax6 expression in the early optic vesicle during a narrow time window. It acts as a \"master control\" gene for the development of eyes and other sensory organs, certain neural and epidermal tissues as well as other homologous structures, usually derived from ectodermal tissues.</p>\n<p><strong>Highyeild:</strong></p><p>PAX6 is expressed on the surface and neuroectoderms at an early stage, then in the differentiating cells in the cornea, lens, ciliary body, and retina through development. PAX6 may play a role in determining cell fate in the morphogenesis of various human ocular tissues. The optic cup formation process is regulated by interactive signals between the optic vesicle and surrounding mesenchyme and the overlying surface ectoderm in the lens-forming region. PAX6 acts in the surface ectoderm to regulate lens development</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. MITF is responsible for pigment epithelium differentiation of neuroepithelium Option A .CHX10 is responsible for neural retinal differentiation of neuroepithelium Option D . cannot be the answer to the above question These genes play an important role in the development of eye and vision.</p>\n<p><strong>Extraedge:</strong></p><p>Fibroblast growth factors (FGFs) from the surface ectoderm promote differentiation of the neural (inner layer) retina, whereas transforming growth factor B (TGF-B), secreted by surrounding mesenchyme, directs the formation of the pigmented (outer) retinal layer. Differentiation of the lens depends on PAX6, although the gene is not responsible for inductive activity by the optic vesicle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Most common location of thyroglossal cyst:", "options": [{"label": "A", "text": "Subhyoid", "correct": true}, {"label": "B", "text": "foramen cecum", "correct": false}, {"label": "C", "text": "in front and below the thyroid", "correct": false}, {"label": "D", "text": "mediastinum", "correct": false}], "correct_answer": "A. Subhyoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Subhyoid Subhyoid (60%)is the most common site of the thyroglossal cyst and is treated by Sistrunk operation.</p>\n<p><strong>Highyeild:</strong></p><p>A thyroglossal cyst may lie at any point along the migratory pathway of the thyroid gland but is always near or in the midline of the neck. It is a cystic remnant of the thyroglossal duct. Although approximately 50% of these cysts are close to or just inferior to the body of the hyoid bone. Sometimes, a thyroglossal cyst is connected to the outside by a fistulous canal, a thyroglossal fistula. Such a fistula usually arises secondarily after the rupture of a cyst but may be present at birth.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Other locations of thyroglossal cyst include b) foramen cecum (2%), in front and below thyroid (13%) d) mediastinal being a site of ectopic thyroid. Ectopic thyroid can be an abnormal position of the thyroid gland anywhere along the path of the thyroglossal duct.</p>\n<p><strong>Extraedge:</strong></p><p>Aberrant thyroid tissue may be found anywhere along the path of descent of the thyroid gland. It is commonly found in the base of the tongue, just behind the foramen cecum, and is subject to the same diseases as the thyroid gland itself.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the tongue muscle not which doesn’t develop from occipital somites:", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": true}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "B. B", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682707160-QTDA084012IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>B B - palatoglossus - 4th pharyngeal arch. Palatoglossus is the only tongue muscle derived from the fourth branchial arch.</p>\n<p><strong>Highyeild:</strong></p><p>Tongue muscles probably differentiate in situ, but most are derived from myoblasts originating in occipital somites. Thus, tongue musculature is innervated by the hypoglossal nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A - styloglossus Option C - hyoglossus Option D – genioglossus Palatoglossus is the only tongue muscle derived from the fourth branchial arch. All the other muscles of the tongue derive from the occipital myotomes. This is the reason that all the other tongue muscles receive innervation from the twelfth cranial nerve (hypoglossal nerve) except the palatoglossus muscle, which is innervated by the tenth cranial nerve (vagus nerve). Genioglossus is the main intrinsic muscle of the tongue responsible for tongue movements.</p>\n<p><strong>Extraedge:</strong></p><p>Palatoglossus arises from the palatine aponeurosis of the soft palate , where it is continuous with the muscle of the opposite side, and passes downward, forward, and lateral ward in front of the palatine tonsil, is inserted into the side of the tongue, some of its fibers spreading over the dorsum, and others passing deeply into the substance of the organ to intermingle with the transverse muscle of the tongue.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Tip of tongue drains into:", "options": [{"label": "A", "text": "Occipital Lymph Node", "correct": false}, {"label": "B", "text": "Submental lymph node", "correct": true}, {"label": "C", "text": "Deep cervical lymph node", "correct": false}, {"label": "D", "text": "Tonsillar lymph node", "correct": false}], "correct_answer": "B. Submental lymph node", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Submental lymph node So, these lymph nodes get enlarged in case of cancer of the tip of the tongue.</p>\n<p><strong>Highyeild:</strong></p><p>The lymphatics emerging from the tongue are grouped into the following four sets: Apical vessels: They drain the tip and inferior surface of the tongue into submental lymph nodes after piercing the mylohyoid muscle. Their efferents go to the submandibular nodes mainly, some cross the hyoid bone to reach the jugulo-omohyoid nodes. Marginal vessels: They drain the marginal portions of the anterior two-third of the tongue—unilaterally into submandibular lymph nodes and then to the lower deep cervical lymph nodes , including jugulo-omohyoid. Central vessels: They drain the central portion of the anterior two-third of the tongue (i.e., the area within 0.5 inches on either side of midline). They pass vertically downwards in the midline of the tongue between the genioglossus muscles and then drain bilaterally into the deep cervical lymph nodes . Basal vessels: They drain the root of the tongue and posterior one-third of the tongue bilaterally into upper deep cervical lymph nodes, including jugulodigastric . Lymphatic drainage of Tongue</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Occipital Lymph Node The occipital group of nodes drains to the sternocleidomastoid nodes or accessory nodes via efferent vessels. The superficial and deep occipital lymph nodes receive lymphatic drainage from the posterior aspect of the scalp, the skin of the upper neck, and a portion of the deep layers of the neck which borders on the occipital region. Option C. Deep cervical lymph node Deep cervical nodal groups drain the efferent lymphatics from the occipital, retro-auricular, occipital, and parietal scalp nodes. It receives direct drainage from the skin of the lateral and posterior neck and shoulder, the nasopharynx, the oropharynx, and the thyroid gland . Option D . Tonsillar lymph node Tonsillar lymph nodes drain tonsils and posterior pharynx.</p>\n<p><strong>Extraedge:</strong></p><p>The mucosa of the pharyngeal part of the dorsal surface of the tongue contains many lymphoid follicles aggregated into dome-shaped groups: the lingual tonsils.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following demarcates the anterior 2/3rd from the posterior 1/3rd of the tongue?", "options": [{"label": "A", "text": "Circumvallate Papillae", "correct": false}, {"label": "B", "text": "Filiform papillae", "correct": false}, {"label": "C", "text": "Sulcus terminalis", "correct": true}, {"label": "D", "text": "Passavant’s ridge", "correct": false}], "correct_answer": "C. Sulcus terminalis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sulcus terminalis It is the junction between anterior 2/3rd and posterior 1/3rd of the tongue and circumvallate papillae are also present anterior to this junction.</p>\n<p><strong>Highyeild:</strong></p><p>The dorsal mucosa of the tongue has a longitudinal median sulcus and is covered by filiform, fungiform, and circumvallate papillae. The dorsal epithelium consists of a superficial stratified squamous epithelium, which varies from non-keratinized stratified squamous epithelium posteriorly, to fully keratinized epithelium overlying the filiform papillae more anteriorly. Dorsum of Tongue</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Circumvallate Papillae Circumvallate papillae : Also known as vallate papillae, 7-11 of these are located on the backside of your tongue, anterior to sulcus terminalis containing over 100 taste buds each . Option B. Filiform papillae Filiform papillae are found in large numbers across the tongue’s surface. They are cone-shaped structures that don’t contain taste buds, so have no taste function. Each papilla has brush-like structures called secondary papillae projecting from its tip. They are abrasive giving the tongue a cleaning, rasping action and helping grip food. Filiform papillae give the tongue a velvety or furry appearance. Option D. Passavant’s ridge The Passavant cushion or ridge is a small prominence in the posterior pharynx, formed from a focal bulge of the superior pharyngeal constrictor muscles during swallowing. The \"cushion\" opposes the soft palate during the act of swallowing and is part of the seal between the soft palate and pharynx that prevents nasopharyngeal reflux.</p>\n<p><strong>Extraedge:</strong></p><p>The tongue and the floor of the mouth are supplied chiefly by the lingual artery, which arises from the anterior surface of the external carotid artery. It passes between the hyoglossus and the middle constrictor of the pharynx to reach the floor of the mouth, accompanied by the lingual veins and the glossopharyngeal nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Waldeyer’s ring is formed by all, except:", "options": [{"label": "A", "text": "Palatine Tonsil", "correct": false}, {"label": "B", "text": "Pharyngeal tonsil", "correct": false}, {"label": "C", "text": "Tubal tonsil", "correct": false}, {"label": "D", "text": "Postauricular nodes", "correct": true}], "correct_answer": "D. Postauricular nodes", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Postauricular nodes The Waldeyer’s ring is formed by: Pharyngeal tonsil (nasopharyngeal tonsil), postero-superiorly. Lingual tonsil, anteroinferiorly. Tubal and palatine tonsils, laterally.</p>\n<p><strong>Highyeild:</strong></p><p>Waldeyer’s ring prevents the invasion of microorganisms from entering the air and food passages and this helps in the defense mechanism of the respiratory and alimentary systems. Waldeyer’s ring</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Palatine Tonsil, Option B. Pharyngeal tonsil, and Option C. Tubal tonsil all lead to the formation of Waldeyer’s ring.</p>\n<p><strong>Extraedge:</strong></p><p>Waldeyer’s ring: These lymphatics can get infected during childhood. The aggregations of lymphoid tissue underneath the epithelial lining of the pharyngeal wall called tonsils, surround the commencement of air and food passages. These aggregations together constitute an interrupted circle called Waldeyer’s ring, which forms the special feature of the interior of the pharynx.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 22 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which statement best describes the posterior medial compartment of the thigh?", "options": [{"label": "A", "text": "The common origin for the posterior thigh muscles (hamstrings) is the ischial spine.", "correct": false}, {"label": "B", "text": "The adductor magnus is a muscle of the posterior compartment of the thigh", "correct": true}, {"label": "C", "text": "The obturator nerve innervates all the hamstring muscles", "correct": false}, {"label": "D", "text": "Both heads of the Biceps femoris take origin from the pelvis", "correct": false}], "correct_answer": "B. The adductor magnus is a muscle of the posterior compartment of the thigh", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The adductor magnus is a muscle of the posterior compartment of the thigh Adductor magnus has a hamstring portion and adductor portion and is, therefore, part of both the medial and posterior compartments and is dually innervated by the obturator and sciatic nerves.</p>\n<p><strong>Highyeild:</strong></p><p>The adductor magnus muscle is a large triangular muscle. It is situated in the posterior and medial fascial compartments of the thigh . The distribution of this muscle in two compartments is reflected in the fact that it receives a dual nerve supply . The adductor magnus is the largest and strongest muscle of the medial compartment of the thigh .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. The common origin for the posterior thigh muscles (hamstrings) is the ischial spine. The common origin of hamstring muscles is ischial tuberosity. Option C. All the hamstring muscles are innervated by the obturator nerve. The tibial part of the sciatic nerve innervates all the muscles of the posterior compartment of the thigh except the short head of the biceps, which is innervated by its common peroneal component of the Sciatic nerve. Option D. Both heads of the Biceps femoris take origin from the pelvis. The biceps femoris has a long head that arises from the ischial tuberosity and a short head that arises from the distal part of the inferolateral aspect of the femur.</p>\n<p><strong>Extraedge:</strong></p><p>Muscles of the back of Thigh Muscle Origin Insertion Innervation Function Biceps femoris Long head-inferomedial part of the upper area of the ischial tuberosity; short head-lateral lip of linea aspera Head of fibula Sciatic nerve (L5, S1 , S2) Flexes leg at knee joint; extends and laterally rotates thigh at hip joint and laterally rotates leg at knee joint Semitendinosus Inferomedial part of the upper area of the ischial tuberosity Medial surface of proximal tibia Sciatic nerve (L5, S1 , S2) Flexes leg at knee joint and extends thigh at hip joint; medially rotates thigh at hip joint and leg at knee joint Semimembranosus Superolateral impression on the ischial tuberosity Groove and adjacent bone on medial and posterior surface of medial tibial condyle Sciatic nerve (L5, S1 , S2 Flexes leg at knee joint and extends thigh at hip joint; medially rotates thigh at hip joint and leg at knee joint</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient came to your clinic with weakness in their leg, difficulty walking, and pain in their leg after walking some distance. On examination, the patient had difficulty flexing the knee and extension at the hip. Which muscle is responsible for flexion at the knee and extension at the hip joint and how is it tested?", "options": [{"label": "A", "text": "Active knee flexion against resistance in the supine or prone position", "correct": true}, {"label": "B", "text": "Adduction of the thigh against resistance in the supine position with the knee extended", "correct": false}, {"label": "C", "text": "Extending the knee against resistance in the supine position with the hip flexed", "correct": false}, {"label": "D", "text": "Lateral rotation of the extended hip and abduction of the flexed hip against resistance", "correct": false}], "correct_answer": "A. Active knee flexion against resistance in the supine or prone position", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Active knee flexion against resistance in the supine or prone position The muscle responsible for flexion at the knee and extension at hip joint is hamstring muscle Hamstring muscles are tested by active knee flexion against resistance in the supine or prone position.</p>\n<p><strong>Highyeild:</strong></p><p>Hamstring Muscle test Then ask your patient to stabilize this position by placing the left hand behind the left knee and the right hand behind the right knee.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:-: Option B. Adduction of the thigh against resistance, in the supine position with the knee extended. Adduction of the thigh against resistance, in the supine position with the knee extended test is done for Adductor muscles. Option C. Extending the knee against resistance in the supine position with the hip flexed. Extending the knee against resistance in the supine position with the hip flexed.This test is done for quadriceps femoris muscle. Option D. Lateral rotation of the extended hip and abduction of the flexed hip against resistance Lateral rotation of the extended hip and abduction of the flexed hip against resistance. This test is done for the obturator externus muscle. It acts as a postural muscle and also adjusts ligaments to maintain stability and integrity.</p>\n<p><strong>Extraedge:</strong></p><p>There are three long muscles in the posterior compartment of the thigh: biceps femoris, semitendinosus, and semimembranosus, collectively known as the hamstrings. All except the short head of the biceps femoris cross both the hip and knee joints. The hamstrings flex the leg at the knee joint and extend the thigh at the hip joint. They are also rotators at both joints.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were playing cricket, and your team opted to field first. You were asked to bowl the first over. As a medical student, you know one group of muscles involved mainly in sport-related injury, you want yourself to be cautious in preventing injury, and you remember this muscle causes flexion at the knee and extension at the hip joint. What is the muscle and its nerve supply?", "options": [{"label": "A", "text": "Quadratus femoris, nerve to quadratus femoris", "correct": false}, {"label": "B", "text": "Quadricep femoris, femoral nerve L2, L3; L4", "correct": false}, {"label": "C", "text": "Biceps femoris; sciatic nerve; profunda femoral artery", "correct": true}, {"label": "D", "text": "Pectineus; femoral nerve L2; L3", "correct": false}], "correct_answer": "C. Biceps femoris; sciatic nerve; profunda femoral artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Biceps femoris; sciatic nerve; profunda femoral artery The posterior thigh muscles, biceps femoris, semitendinosus and semimembranosus and ischial part of adductor magnus muscles are called the ‘hamstrings' group of muscles. They cross both hip and knee joints and integrate extension at the hip with flexion at the knee. The posterior compartment muscles receive their blood supply from the perforating branches of the profunda femoris artery , most notably through the first perforator. All hamstring muscles are supplied by the sciatic nerve's tibial branch except the biceps femoris's short head, supplied by the common fibular nerve.</p>\n<p><strong>Highyeild:</strong></p><p>The biceps femoris flexes the leg at the knee joint. The long head also extends and laterally rotates the hip. When the knee is partly flexed, the biceps femoris can laterally rotate the leg at the knee joint. The long head is innervated by the tibial division of the sciatic nerve, and the short head is innervated by the common fibular division of the sciatic nerve. Hamstring Muscles</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Quadratus femoris, nerve to quadratus femoris The quadratus femoris is a flat, quadrilateral skeletal muscle . It is located on the posterior side of the hip joint, a strong external rotator and adductor of the thigh. It also stabilises the femoral head in the acetabulum. The nerve innervates it to quadratus femoris (L4-S1). Option B. Quadricep femoris, femoral nerve L2, L3; L4 The quadratus femoris is a flat, quadrilateral skeletal muscle . It is located on the posterior side of the hip joint, a strong external rotator and adductor of the thigh. It also stabilises the femoral head in the acetabulum. The nerve innervates it to quadratus femoris (L4-S1). Option D. Pectineus; femoral nerve L2; L3 The pectineus muscle is a flat, quadrangular muscle situated at the anterior part of the upper and medial aspect of the thigh. The pectineus muscle is the most anterior adductor of the hip. The muscle adducts and internally rotates the thigh, but its primary function is hip flexion. It is Innervated by Femoral and Obturator nerves.</p>\n<p><strong>Extraedge:</strong></p><p>The largest branch of the femoral artery in the thigh is the deep artery of the thigh (profunda femoris artery), which originates from the lateral side of the femoral artery in the femoral triangle and is the major source of blood supply to the thigh.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An athlete was brought to the clinic complaining of pain and inability to move his leg while participating in a sprinting competition. While sprinting, he fell on the ground midway. He is an amateur athlete who didn't warm up before the race. On examination, you notice difficulty in the lateral rotation of the leg at the knee joint. What is the origin and insertion of muscle responsible for this?", "options": [{"label": "A", "text": "Ischial tuberosity and upper part of the medial surface of the shaft of the tibia", "correct": false}, {"label": "B", "text": "Ischial tuberosity and medial condyle of tibia", "correct": false}, {"label": "C", "text": "Ischial tuberosity and head of the fibula", "correct": true}, {"label": "D", "text": "Ischial tuberosity and adductor tubercle of femur", "correct": false}], "correct_answer": "C. Ischial tuberosity and head of the fibula", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ischial tuberosity and head of the fibula The biceps femoris is the muscle responsible for lateral leg rotation at the knee joint. It originates from ischial tuberosity (long head) and is inserted into the head of the fibula.</p>\n<p><strong>Highyeild:</strong></p><p>Muscle of Back of Thigh Muscle Origin Insertion Nerve supply Biceps femoris (a) Long head (a) Long head: From lower medial part of upper quadrilateral area of ischial tuberosity Into the head of the fibula in front of its styloid process (a) Long head, by the tibial part of the sciatic nerve (L5; S1, S2) (b) Short head (b) Short head: From lateral lip of the linea aspera and from the upper two-third of the lateral supracondylar line (b) Short head by the common peroneal part of the sciatic nerve (L5; S1, S2) Semitendinosus From the lower medial part of upper quadrilateral area of the ischial tuberosity, Into the upper part of the medial surface of the tibia Tibial part of the sciatic nerve (L5; S1, S2) Semimembranosus From the upper lateral part of upper quadrilateral area of ischial tuberosity Into the horizontal groove on the posterior aspect of the medial condyle of the tibia Tibial part of the sciatic nerve (L5; S1, S2) Ischial part of adductor magnus From inferolateral aspect of the ischial tuberosity Into the adductor tubercle Tibial part of the sciatic nerve (L5; S1, S2)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Ischial tuberosity and upper part of the medial surface of shaft of tibia Semitendinosus muscle is a fusiform muscle that arises from the ischial tuberosity and ends a little below the middle of the thigh in a long round tendon that lies along the medial side of the popliteal fossa; it then curves around the medial condyle of the tibia and passes over the medial collateral ligament of the knee-joint, from which it is separated by a bursa, and is inserted into the upper part of the medial surface of the body of the tibia, nearly as far forward as its anterior crest. Option B. Ischial tuberosity and medial condyle of tibia The semimembranosus muscle is the most medial of the three hamstring muscles in the thigh. It is so named because it has a flat tendon of origin. It lies posteromedially in the thigh, deep to the semitendinosus muscle. It originates from the ischial tuberosity and inserts on the medial condyle of the tibia, medial margin of the tibia, lateral condyle of the femur and fascia of the popliteus muscle. Option D. Ischial tuberosity and adductor tubercle of femur The adductor magnus muscle originates from the ischial tuberosity and inserts on the adductor tubercle of the</p>\n<p><strong>Extraedge:</strong></p><p>Expansions from the Semimembranosus tendon also insert into and contribute to the formation of ligaments and fascia around the knee joint. The semimembranosus flexes the leg at the knee joint and extends the thigh at the hip joint. Working with the semitendinosus muscle, it medially rotates the thigh at the hip joint and the leg at the knee joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A person was involved in RTA following a collision with a cow, following which he was experiencing pain and swelling. An X-ray revealed the right upper part of the fibula fracture. The patient was treated conservatively, but on the 3rd day, the patient came to the doctor unable to hold the footwear on the right leg and lift the leg. The doctor diagnosed a foot drop due to a fibula fracture. Foot drop is due to a nerve. Which muscle does it supply in the posterior compartment of the thigh?", "options": [{"label": "A", "text": "Semimembranosus", "correct": false}, {"label": "B", "text": "Semitendinosus", "correct": false}, {"label": "C", "text": "Long head biceps femoris", "correct": false}, {"label": "D", "text": "Short head biceps femoris", "correct": true}], "correct_answer": "D. Short head biceps femoris", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Short head biceps femoris Short head biceps femoris is the only muscle of the posterior compartment of the thigh supplied by the common peroneal nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Biceps Femoris The biceps femoris muscle belly of the long head crosses the posterior thigh obliquely from medial to lateral and is joined by the short head distally. Together, fibres from the two heads form a tendon, which is palpable on the lateral side of the distal thigh. The main part of the tendon inserts into the lateral surface of the head of the fibula. Extensions from the Biceps femoris tendon blend with the fibular collateral ligament and with ligaments associated with the lateral side of the knee joint.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - semimembranosus supplied by the tibial nerve branch of the sciatic nerve Option B - Semitendinosus supplied by the tibial nerve branch of the sciatic nerve Option D - long head of biceps femoris supplied by tibial nerve branch of the sciatic nerve</p>\n<p><strong>Extraedge:</strong></p><p>The semitendinosus muscle is medial to the biceps femoris muscle in the posterior compartment of the thigh. It originates with the long head of the biceps femoris muscle from the inferomedial part of the upper area of the ischial tuberosity. The spindle-shaped muscle belly ends in the lower half of the thigh and forms a long cord-like tendon, which lies on the semimembranosus muscle and descends to the knee. The tendon curves around the medial condyle of the tibia and inserts into the medial surface of the tibia just posterior to the tendons of the gracilis and sartorius muscles as part of the pes anserinus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The posterior compartment muscles receive their blood supply from the perforating branches of the profunda femoris artery, most importantly through the first perforator given off from this artery. This vessel has important anastomoses with which of the given artery?", "options": [{"label": "A", "text": "Superficial external pudendal artery", "correct": false}, {"label": "B", "text": "Inferior gluteal artery", "correct": true}, {"label": "C", "text": "Descending genicular artery", "correct": false}, {"label": "D", "text": "Deep external pudendal artery", "correct": false}], "correct_answer": "B. Inferior gluteal artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior gluteal artery The posterior compartment muscles receive their blood supply from the perforating branches of the profunda femoris artery , most notably through the first perforator given off from this artery. This vessel has important anastomoses with the inferior gluteal artery (on or within semitendinosus) and the medial circumflex femoral artery.</p>\n<p><strong>Highyeild:</strong></p><p>Anastomosis around the back of thigh</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - The superficial external pudendal artery arises medially from the femoral artery , close to the preceding branches. Emerging from the cribriform fascia, it passes medially, usually deep to the long saphenous vein, across the spermatic cord (or round ligament) to supply the lower abdominal, penile, scrotal or labial skin, and anastomoses with branches of the internal pudendal artery. Option C - Descending genicular artery-anastomoses with the inferior medial genicular artery. Option D - Deep external pudendal artery-The deep external pudendal artery passes medially across the pectineus and anterior or posterior to adductor longus, covered by fascia lata, which it pierces to supply the skin of the perineum and scrotum or labium majus. Its branches are anastomose with the internal pudendal artery's posterior scrotal or labial branches .</p>\n<p><strong>Extraedge:</strong></p><p>The obturator artery originates as a branch of the internal iliac artery in the pelvic cavity and enters the medial compartment of the thigh through the obturator canal. As it passes through the canal, it bifurcates into an anterior branch and a posterior branch, which together form a channel that circles the margin of the obturator membrane and lies within the attachment of the obturator externus muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The posterior compartment muscles receive their blood supply from the perforating branches of the profunda femoris artery. The third perforator anastomoses usually with:", "options": [{"label": "A", "text": "Superficial external pudendal artery", "correct": false}, {"label": "B", "text": "Inferior gluteal artery", "correct": false}, {"label": "C", "text": "Superior medial genicular artery", "correct": true}, {"label": "D", "text": "Deep external pudendal artery", "correct": false}], "correct_answer": "C. Superior medial genicular artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior medial genicular artery The third perforator anastomoses with the superior medial genicular artery within the short head of the biceps femoris.</p>\n<p><strong>Highyeild:</strong></p><p>Branches of Profunda femoris artery</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - Superficial external pudendal artery The superficial external pudendal artery arises medially from the femoral artery , close to the preceding branches. Emerging from the cribriform fascia, it passes medially, usually deep to the long saphenous vein, across the spermatic cord (or round ligament) to supply the lower abdominal, penile, scrotal or labial skin, and anastomoses with branches of the internal pudendal artery. Option B - Inferior gluteal artery The posterior compartment muscles receive their blood supply from the perforating branches of the profunda femoris artery , most notably through the first perforator given off from this artery. This vessel has important anastomoses with the inferior gluteal artery (on or within semitendinosus) and the medial circumflex femoral artery. Option D - Deep external pudendal artery The deep external pudendal artery passes medially across the pectineus and anterior or posterior to the adductor longus, covered by fascia lata, which it pierces to supply the skin of the perineum and scrotum or labium majus. Its branches are anastomose with the internal pudendal artery's posterior scrotal or labial branches .</p>\n<p><strong>Extraedge:</strong></p><p>Peripheral vascular disease is often characterised by reduced blood flow to the legs. This disorder may be caused by stenoses (narrowing) and/or occlusions (blockages) in the lower aorta and the iliac, femoral, tibial, and fibular vessels. Patients typically have chronic leg ischemia and \"acute on chronic\" leg ischemia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were posted in the forensic department where your professor was doing a post mortem of a body, which was beaten to death by a mob. There was a lot of muscle tear in the body. Your professor showed you the hamstring muscle and questioned you- among this group of muscles originating from the ischial tuberosity; one muscle has a different nerve supply than others. What are the nerve and the muscle it supplies?", "options": [{"label": "A", "text": "The long head of biceps femoris and common fibular nerve", "correct": false}, {"label": "B", "text": "The short head of biceps femoris and common fibular nerve", "correct": true}, {"label": "C", "text": "Semitendinosus and tibial nerve", "correct": false}, {"label": "D", "text": "Semimembranosus and tibial nerve", "correct": false}], "correct_answer": "B. The short head of biceps femoris and common fibular nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The short head of biceps femoris and common fibular nerve Biceps femoris muscle is supplied by the terminal branches of the sciatic nerve . The long head receives innervation from its tibial division, while the common fibular division innervates the short .</p>\n<p><strong>Highyeild:</strong></p><p>Nerve supply of hamstring muscles</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Long head of biceps femoris and common fibular nerve The long head of Biceps femoris receives innervation from the tibial division of Sciatic nerve. Option C. Semitendinosus and tibial nerve The tibial component of the sciatic nerve innervates Semitendinosus. Option D. Semimembranosus and tibial nerve The tibial component of the sciatic nerve innervates Semimembranosus.</p>\n<p><strong>Extraedge:</strong></p><p>The common criteria of hamstring muscles are: Muscles should originate from the ischial tuberosity. Muscles should be i nserted over the knee joint, in the tibia or the fibula. The tibial branch of the sciatic nerve will innervate muscles . Muscles will participate in flexion of the knee joint and extension of the hip joint. Those muscles that fulfil all four criteria are called true hamstrings. The adductor magnus reaches only up to the adductor tubercle of the femur. Still, i t is included among the hamstrings because the tibial collateral ligament of the knee joint morphologically is the degenerated tendon of this muscle. The ligament is attached to the medial epicondyle, two millimetres from the adductor tubercle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 18 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 41-year-old male came to a casualty with complaints of shortness of breath, dizziness, and sharp chest pain. The large arrow in his chest radiograph indicates the region of pathology (Image). What is this structure?", "options": [{"label": "A", "text": "Superior Vena Cava", "correct": false}, {"label": "B", "text": "Right ventricle", "correct": false}, {"label": "C", "text": "Left ventricle", "correct": false}, {"label": "D", "text": "Arch of the aorta", "correct": true}], "correct_answer": "D. Arch of the aorta", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682853400-QTDA087001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Arch of the aorta The area indicated by the arrow is just inferior to the clavicle (on the left side), and this marks the location of the arch of the aorta.</p>\n<p><strong>Highyeild:</strong></p><p>Normal chest x-ray labeled (PA View)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Superior Vena Cava The normal position of the heart as seen in a plain radiograph has the right border of the heart formed by the superior vena cava, right atrium, and inferior vena cava. Option B. Right ventricle The superior vena cava and right ventricle would make up the right border. The pulmonary artery and left ventricle would be inferior. Option C. Left ventricle The left border is formed by the aortic arch superiorly, the left pulmonary artery, the left auricle, the left ventricle, and the apex of the heart on the inferolateral aspect.</p>\n<p><strong>Extraedge:</strong></p><p>The normal apex beat can be palpated in the precordium left 5th intercostal space, half-inch medial to the left midclavicular line, and 3–4 inches left of the left border of the sternum. In children, the apex beat occurs in the fourth rib interspace medial to the nipple. The apex beat may also be found at abnormal locations; in many cases of dextrocardia, the apex beat may be felt on the right side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 62-year-old male came to a casualty with a complaint of severe chest pain. Physical examination reveals acute myocardial infarction. After the patient is stabilized, angiography is performed and the ejection fraction of the left ventricle is shown to be reduced to 30% of normal values. A cardiac pacemaker is placed to prevent fatal arrhythmias (Image). What is the location of the tip of the pacemaker?", "options": [{"label": "A", "text": "Right Atrium", "correct": false}, {"label": "B", "text": "Left atrium", "correct": false}, {"label": "C", "text": "Right ventricle", "correct": true}, {"label": "D", "text": "Left ventricle", "correct": false}], "correct_answer": "C. Right ventricle", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682853403-QTDA087002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right ventricle Artificial pacemakers are commonly used to treat patients who have weak or failing heart conduction systems. The electrode or “tip” of the pacemaker is threaded through the subclavian vein to the superior vena cava into the right atrium and then the right ventricle where it is used to stimulate the Purkinje fibers to result in ventricular contraction.</p>\n<p><strong>Highyeild:</strong></p><p>Percutaneous Coronary Intervention This is a technique in which a long fine tube (a catheter) is inserted into the femoral artery in the thigh and passed through the external and common iliac arteries and into the abdominal aorta. It continues to be moved upward through the thoracic aorta to the origins of the coronary arteries. The coronaries may also be approached via the radial or brachial arteries.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options A & B. Right Atrium & Left Atrium The right atrium and left atrium do not contain Purkinje fibers and would therefore not be useful in artificially pacing the heart. Option D. Left ventricle The left ventricle is more difficult to access. The superior vena cava is not related to cardiac pacing.</p>\n<p><strong>Extraedge:</strong></p><p>Coronary Artery Bypass Grafts If coronary artery disease is too extensive to be treated by percutaneous intervention, surgical coronary artery bypass grafting may be necessary. The great saphenous vein, in the lower limb, is harvested and used as a graft. It is divided into several pieces, each of which is used to bypass blocked sections of the coronary arteries. The internal thoracic and radial arteries can also be used.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You are concerned with your patient that he may have compromised the function of the mitral valve. The sound of the mitral valve is best heard at which of the following locations?", "options": [{"label": "A", "text": "At the apex in the left fifth intercostal space in the midclavicular line", "correct": true}, {"label": "B", "text": "At the xiphisternal junction", "correct": false}, {"label": "C", "text": "In the fifth intercostal space to the right of the sternum", "correct": false}, {"label": "D", "text": "In the second intercostal space to the left of the sternum", "correct": false}], "correct_answer": "A. At the apex in the left fifth intercostal space in the midclavicular line", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>At the apex in the left fifth intercostal space in the midclavicular line There is only one point of the heart that can be directly identified on the precordium: the apex. A cardiac impulse may be visible at the apex, and palpation over it confirms the presence of the apex beat. The apex is located in the left fifth intercostal space just medial to the midclavicular line, and is the point where the mitral valve is best heard.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. None of the heart sounds are best heard at the xiphisternal junction. Option: C. The tricuspid valve is best heard in the fifth intercostal space to the right of the sternum. Option: D. The pulmonary valve is best heard in the second intercostal space to the left of the sternum. The aortic valve is best heard in the second intercostal space to the right of the sternum.</p>\n<p><strong>Extraedge:</strong></p><p>In healthy adults, there are two normal heart sounds, often described as a lub and a dub that occur in sequence with each heartbeat. These are the first heart sound (S 1 ) and second heart sound (S 2 ), produced by the closing of the atrioventricular valves and semilunar valves, respectively.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 49-year-old woman is admitted to the hospital complaining of severe, crushing, retrosternal pain during the preceding hour. An ECG reveals that she is suffering from acute myocardial infarction in the posterior aspect of her left ventricle and posteromedial papillary muscle. A coronary angiogram is performed and the patient is found to have left coronary dominant circulation. Which of the following arteries is the most likely to be occluded?", "options": [{"label": "A", "text": "Artery of the conus", "correct": false}, {"label": "B", "text": "Right coronary artery", "correct": false}, {"label": "C", "text": "Circumflex", "correct": true}, {"label": "D", "text": "Right acute marginal", "correct": false}], "correct_answer": "C. Circumflex", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Circumflex A “left coronary dominant” circulation means, most simply, that the left coronary artery (LCA) provides the posterior interventricular artery as a terminal branch of the coronary circumflex. The posterior aspect of the heart is composed primarily of the left ventricle and is supplied by the posterior interventricular branch.</p>\n<p><strong>Highyeild:</strong></p><p>Coronary Artery Disease Occlusion of a major coronary artery, usually due to atherosclerosis, leads to inadequate oxygenation of an area of the myocardium and cell death. The severity of the problem will be related to the size and location of the artery involved, whether or not the blockage is complete, and whether there are collateral vessels to provide perfusion to the territory from other vessels.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Artery of the conus The artery of the conus supplies the right ventricular free wall. If the right coronary artery were occluded (in a right coronary dominant heart), it would affect the right atrium, right ventricle, the sinoatrial and atrioventricular nodes, the posterior part of the interventricular septum, and part of the posterior aspect of the left ventricle. Option B. Right coronary artery The patient is found to have left coronary dominant circulation in question. Option D. Right acute marginal The right acute marginal artery supplies the inferior margin of the right ventricle.</p>\n<p><strong>Extraedge:</strong></p><p>The left diagonal arteries arise most commonly from the anterior interventricular (left anterior descending) artery but can also arise as branches of the left coronary or the circumflex.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 70-year-old male with a history of two previous myocardial infarctions is admitted to the hospital with severe chest pain. ECG reveals a new myocardial infarction and ventricular arrhythmia. Coronary angiography reveals that the right coronary artery is blocked just distal to the origin of the right marginal artery in a right coronary dominant circulation. Which of the following structures would most likely be affected after such a blockade?", "options": [{"label": "A", "text": "Right Atrium", "correct": false}, {"label": "B", "text": "SA node", "correct": false}, {"label": "C", "text": "AV node", "correct": true}, {"label": "D", "text": "Lateral wall of the left ventricle", "correct": false}], "correct_answer": "C. AV node", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>AV node The atrioventricular (AV) node is most commonly supplied by a branch of the right coronary artery. This branch arises at the crux of the heart (the point of junction of all four cardiac chambers posteriorly); this is the location of the occlusion.</p>\n<p><strong>Highyeild:</strong></p><p>The atrioventricular node or AV node electrically connects the heart's atria and ventricles to coordinate beating at the top of the heart; it is part of the electrical conduction system of the heart. The AV node lies at the lower back section of the interatrial septum near the opening of the coronary sinus and conducts the normal electrical impulse from the atria to the ventricles.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. & B - Right Atrium & SA node The right atrium is supplied by the right coronary artery, which additionally supplies the sinoatrial node. Option D. Lateral wall of the left ventricle The left marginal artery supplies the lateral wall of the left ventricle. The anterior portion of the interventricular septum is supplied by the anterior interventricular artery.</p>\n<p><strong>Extraedge:</strong></p><p>The blood supply of the AV node is from the atrioventricular nodal branch. The origin of this artery is most commonly (80–90% of hearts) a branch of the right coronary artery, with the remainder originating from the left circumflex artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The sinoatrial (SA) node initiates the heartbeat by giving off an impulse about 80 times per minute. It is located at the junction of the superior vena cava and the right atrium. In about 60% of the cases, the SA node derives its vascular supply from which of the following?", "options": [{"label": "A", "text": "Anterior Interventricular Artery", "correct": false}, {"label": "B", "text": "Left circumflex artery", "correct": false}, {"label": "C", "text": "Posterior interventricular artery", "correct": false}, {"label": "D", "text": "Right coronary artery", "correct": true}], "correct_answer": "D. Right coronary artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right coronary artery In 60% of patients, the right coronary artery supplies the SA node. In a third of the population, the SA node is supplied by the left coronary artery, and in some patients it receives branches from both the right and the left.</p>\n<p><strong>Highyeild:</strong></p><p>The origin of the sinoatrial node artery is not related to coronary artery dominance, which means the side (right or left) that provides circulation to the back of the heart. In contrast, the atrioventricular nodal branch, which is the artery that brings blood to the atrioventricular node, depends on coronary artery dominance.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Anterior Interventricular Artery The anterior interventricular and left circumflex arteries are distal branches of the left coronary artery, too distant to supply the SA node. Option B. Left circumflex artery SA nodal artery arises from the right coronary artery in around 60% of individuals, from the left circumflex coronary artery in about 40% of individuals, and in less than 1% of humans, the artery has an anomalous origin directly from the coronary sinus, descending aorta, or distal right coronary artery. Option C. Posterior interventricular artery The right coronary artery normally gives out its SA nodal branch in its proximal portion and then distally gives rise to the right marginal and posterior interventricular arteries. These are also too distant to supply the SA node.</p>\n<p><strong>Extraedge:</strong></p><p>The sinoatrial node ( sinus node ) is an oval-shaped region of special cardiac muscle in the upper back wall of the right atrium made up of cells known as pacemaker cells. The sinus node is approximately 15 mm long, 3 mm wide, and 1 mm thick, located directly below and to the side of the superior vena cava.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Regarding the heart muscle, all are true except:", "options": [{"label": "A", "text": "Acts As Syncytium", "correct": false}, {"label": "B", "text": "Has multiple nuclei", "correct": true}, {"label": "C", "text": "Has gap junctions", "correct": false}, {"label": "D", "text": "Has branching", "correct": false}], "correct_answer": "B. Has multiple nuclei", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Has multiple nuclei CARDIAC MUSCLE Cardiac muscle cells usually have a single (central) nucleus. The cells are often branched and are tightly connected by specialized junctions. The region where the ends of the cells are connected to another cell is called an intercalated disc.</p>\n<p><strong>Highyeild:</strong></p><p>Cardiac muscle, like skeletal muscle, is made up of sarcomeres that allow for contractility. However, unlike skeletal muscle, cardiac muscle is under involuntary control. The heart is made up of three layers—pericardium, myocardium, and endocardium. The endocardium is not cardiac muscle. It is composed of simple squamous epithelial cells and forms the inner lining of the chambers of the heart and valves. The pericardium is a fibrous sac surrounding the heart, consisting of the epicardium, pericardial space, parietal pericardium, and fibrous pericardium.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Acts As Syncytium Cardiac muscle cells are the contracting cells that allow the heart to pump. Each cardiomyocyte needs to contract in coordination with its neighboring cells - known as a functional syncytium - working to efficiently pump blood from the heart, and if this coordination breaks down then – despite individual cells contracting – the heart may not pump at all, such as may occur during abnormal heart rhythms such as ventricular fibrillation. Option C. Has gap junctions Mitochondria are larger and more abundant in cardiac fibers Gap junctions couple all fibers for rhythmic contraction and form the functional syncytium. Option D. Has branching Cardiac muscle cells (cardiomyocytes) are striated, branched, contain many mitochondria, and are under involuntary control. Each myocyte contains a single, centrally located nucleus and is surrounded by a cell membrane known as the sarcolemma.</p>\n<p><strong>Extraedge:</strong></p><p>The functional unit of cardiomyocyte contraction is the sarcomere, which consists of thick (myosin) and thin (actin) filaments, the interactions between which form the basis of the sliding filament theory.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The collecting tubule of the kidney develops from which of the following structure:", "options": [{"label": "A", "text": "Metanephric Blastema", "correct": false}, {"label": "B", "text": "Genital ridge", "correct": false}, {"label": "C", "text": "Urogenital sinus", "correct": false}, {"label": "D", "text": "Ureteric bud", "correct": true}], "correct_answer": "D. Ureteric bud", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ureteric bud Collecting tubules along with the collecting system of the kidney develop from the ureteric bud. Ureteric bud can form the collecting part of the kidney which helps in urine collection and excretion.</p>\n<p><strong>Highyeild:</strong></p><p>The ureteric bud arises from the mesonephric duct and grows cranially behind the peritoneal cavity towards the meta-nephros. The distal end of the ureteric bud becomes capped by metanephric blastema . The growing end of the ureteric bud becomes dilated like a funnel to form the pelvis of the ureter/renal pelvis. The ureteric bud divides dichotomously and its 13 generations form the collecting system of the kidney. The renal pelvis undergoes repeated divisions to form major calyces, minor calyces, collecting ducts, and collecting tubules</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Metanephric Blastema Metanephric blastema forms the secretary system of the kidney which includes PCT, DCT, the loop of Henle, Bowman’s capsule, and connecting tubules. Option B. Genital ridge Genital ridge forms gonads. Option C. Urogenital sinus The urogenital sinus forms the bladder, the lower part of the vagina.</p>\n<p><strong>Extraedge:</strong></p><p>Development of the kidney and ureter Embryonic structures Adult derivatives Ureteric bud Ureter Renal pelvis Major calyces Minor calyces Collecting ducts Collecting tubules Metanephric blastema Renal glomerulus Renal (Bowman's) capsule Proximal convoluted tubule Loop of Henle Distal convoluted tubule</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are derivatives of urogenital sinus except :", "options": [{"label": "A", "text": "Greater Vestibular Glands", "correct": false}, {"label": "B", "text": "Bulbourethral glands", "correct": false}, {"label": "C", "text": "Prostatic urethra distal to the utricle", "correct": false}, {"label": "D", "text": "Prostatic utricle", "correct": true}], "correct_answer": "D. Prostatic utricle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Prostatic utricle Prostatic utricle arises from the paramesonephric duct in males.</p>\n<p><strong>Highyeild:</strong></p><p>The prostatic gland develops from five epithelial buds that arise from the epithelial lining of the prostatic urethra and grow in the surrounding mesoderm. These are one anterior, two posterior, and two lateral. The buds arising from the mesodermal posterior wall of the urethra above the openings of ejaculatory ducts form the inner glandular zone of the gland while the buds arising from the rest of the prostatic urethra (endodermal in origin) form the outer glandular zone of the prostate. The surrounding mesoderm forms dense fibrous stroma and smooth muscle of the prostate gland. It also forms the prostatic capsule.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Greater Vestibular Glands Greater vestibular glands are derivatives of the urogenital sinus in females, These glands help in the lubrication of the vestibular area. Option B. Bulbourethral glands Bulbourethral glands are formed from the urogenital sinus in males. Option C. Prostatic urethra distal to the utricle The prostatic urethra is distal to the utricle and is formed from the urogenital sinus in males.</p>\n<p><strong>Extraedge:</strong></p><p>Embryonic structures and their homologous adult derivatives in male and female Embryonic structure Adult derivatives In male In female 1. Indifferent gonad (a) Primordial germ cells (b) Surface epithelium of gonad (c) Mesenchyme Testis Spermatogonia Sertoli cells/supporting cells Leydig cells (interstitial cells) Ovary Oogonia Follicular cells Theca cells (forming theca interna and externa) 2. Gubernaculum Gubernaculum testis (a) Round ligament of ovary (b) Round ligament of uterus 3. Mesonephric tubules (a) Cranial tubules (b) Caudal tubules Efferent ductules Paradidymis Epoophoron Paroophoron 4. Mesonephric duct Duct of epididymis Vas deferens Seminal vesicle Ejaculatory duct Gartner's duct 5. Paramesonephric duct Appendix of testis Prostatic utricle Uterine tubes Uterus Cervix Upper part of vagina 6. Urogenital sinus Urinary bladder Urethra (prostatic membranous and penile) Prostate gland Bulbourethral glands Urinary bladder Urethra (membranous) and vestibule of vagina Paraurethral glands (of Skene) Greater vestibular glands 7. Mullerian tubercle Seminal colliculus (verumontanum) Hymen 8. Genital tubercle Penis Clitoris 9. Urethral folds Penile urethra Labia minora 10. Genital swellings Scrotum Labia majora</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Total or partial failure of fusion of the terminal part of paramesonephric ducts in females gives rise to all of the following except:", "options": [{"label": "A", "text": "Uterus didelphys with double vagina", "correct": false}, {"label": "B", "text": "Bicornuate bicollis", "correct": false}, {"label": "C", "text": "Uterus bicornis unicollis", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. Uterus bicornis unicollis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Uterus bicornis unicollis A bicornuate uterus or bicornate uterus is a type of Mullerian anomaly in the human uterus, where there is a deep indentation at the fundus (top) of the uterus. The bicornuate uterus is typically classified based on whether or not the division extends to the external cervical os. Bicornuate uteri with a division above the os are called bicornuate unicollis and those with a divided os are called bicornuate bicollis.</p>\n<p><strong>Highyeild:</strong></p><p>During the first stage of development, the superior aspect of each Müllerian duct develops into the left and right fallopian tubes, while the more caudal portions of each duct develop into the left and right uterus, cervix, and upper 2/3 of the vagina. The lower 1/3 of the vagina develops from the urogenital sinus and the ovaries develop from the gonadal ridge, independent of the Müllerian ducts. During the second stage, there is midline fusion of the separate left and right uterus, cervix, and upper vagina. During the third stage of development, there is resorption of the midline fused segments in the uterus, cervix, and upper vagina, resulting in a single upper, mid, and lower uterine cavity, and single cervical and vaginal canals. The resorption can begin at any level and be incomplete. By the end of the first trimester, the development of the Müllerian duct system is complete.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Uterus didelphys with double vagina Complete failure of fusion of Paramesonephric Ducts results in uterus didelphys, a condition in which the uterine body, cervical canal, and cranial vagina are all duplicated. Option B. Bicornuate bicollis A bicornuate uterus is divided according to the involvement of the cervical canal: bicornuate bicollis: two cervical canals; central myometrium extends to the external cervical os. bicornuate unicollis: one cervical canal; central myometrium extends to the internal cervical os. Option D. None of the above Bicornuate uteri with a division above the os are called bicornuate unicollis and those with a divided os are called bicornuate bicollis.</p>\n<p><strong>Extraedge:</strong></p><p>Three embryological stages of normal uterine, cervical, and vaginal development. Stage I: Two separate uterine, cervical, and vaginal segments develop. The upper 2/3 of the vagina develops with a transverse septum along the caudal aspect. This transverse septum will dissolve when the lower 1/3 of the vagina, which develops from the urogenital sinus, fuses with the upper 2/3 of the vagina. Stage II: Midline fusion of the uterine, cervical, and vaginal segments. Stage III: Degeneration of the midline fused segments in the uterus, cervix, and vagina. Three embryologic stages of normal uterine, cervical, and vaginal development.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about Ectopia cloacae:", "options": [{"label": "A", "text": "The anal membrane becomes elongated and ruptures to the whole of its extent before anorectal septum formation.", "correct": false}, {"label": "B", "text": "Anal musculature is present but not associated with the anal canal.", "correct": false}, {"label": "C", "text": "Failure of Mesenchyme migration around the ventral body wall to support the umbilical cord leads to a large abdominal defect.", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above Failure of Mesenchyme migration around the ventral body wall to support the umbilical cord leads to a large abdominal defect . Ectopia cloacae are formed due to failure of Mesenchyme migration around the ventral body wall to support the umbilical cord leading to a large abdominal defect with a central colonic portion with bilateral bladder components and hence option c) is correct Cloacae is a common point for the junction of the urinary and GI system .</p>\n<p><strong>Highyeild:</strong></p><p>A vesica-intestinal fissure or exstrophy of the cloaca is a rare but serious birth defect of the urogenital tract and distal part of the digestive tract. The most important hallmarks are: bladder exstrophy, the fusion between the bladder and the exstrophy ileocecal region, short blind-ending colon, and imperforate anus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Anal membrane becomes elongated and ruptures to the whole of its extent before anorectal septum formation. The anal membrane becomes elongated and ruptures to the whole of its extent before anorectal septum formation in cases of ectopia cloacae. Option B. Anal musculature is present but not associated with anal canal. Anal musculature is present but not associated with anal canal is also true about ectopia cloacae.</p>\n<p><strong>Extraedge:</strong></p><p>The term “ectopia cloacae” will be replaced by the purely one-word “vesica-intestinal fissure.”</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In males, the prostatic urethra proximal to the prostatic utricle is formed from which of the following structure:", "options": [{"label": "A", "text": "Vesicourethral part of the cloaca and the caudal end of the mesonephric duct", "correct": true}, {"label": "B", "text": "Urogenital sinus", "correct": false}, {"label": "C", "text": "Genital swelling", "correct": false}, {"label": "D", "text": "Genital ridge", "correct": false}], "correct_answer": "A. Vesicourethral part of the cloaca and the caudal end of the mesonephric duct", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Vesicourethral part of the cloaca and the caudal end of the mesonephric duct In males, the prostatic urethra proximal to the prostatic utricle is formed from the vesicourethral part of the cloaca and caudal end of the mesonephric duct.</p>\n<p><strong>Highyeild:</strong></p><p>DEVELOPMENT OF THE MALE URETHRA The part of the male urethra extending from the urinary bladder up to the openings of the ejaculatory ducts (original openings of mesonephric ducts) is derived from the caudal part of the vesicourethral canal (endoderm). The posterior wall of this part is derived from absorbed mesonephric ducts (mesoderm). (It may later be overgrown by endoderm). The rest of the prostatic urethra , and the membranous urethra , are derived from the pelvic part of the definitive urogenital sinus . The penile part of the urethra (except the terminal part) is derived from the epithelium of the phallic part of the definitive urogenital sinus. The terminal part of the penile urethra that lies in the glans is derived from the ectoderm.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Urogenital sinus The urogenital sinus forms the remaining part of the prostatic urethra and Membranous urethra . Option C. Genital swelling Genital swelling forms the scrotum in males whereas it forms labia majora in females. Option D. Genital ridge Genital ridge forms testis in male</p>\n<p><strong>Extraedge:</strong></p><p>DEVELOPMENT OF THE FEMALE URETHRA The female urethra is derived from the caudal part of the vesicourethral canal (endoderm). The posterior wall of this canal is derived from the mesonephric ducts and is, therefore, mesodermal in origin. The female urethra may receive a slight contribution from the pelvic part of the urogenital sinus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 15-year-old male patient came to the emergency department for an acute right inguinal pain lasting more than 6hrs. No recent increase in the volume of either testicle was noticeable. There was no history of urinary symptoms, nor scrotal pain due to trauma, but an undescended right testicle was diagnosed at the age of 3 years. The causes for the descent of the testis during intrauterine life are all except:", "options": [{"label": "A", "text": "Formation of Gubernaculum", "correct": false}, {"label": "B", "text": "Intra-abdominal temperature and pressure", "correct": false}, {"label": "C", "text": "Maternal gonadotropins and male sex hormones", "correct": false}, {"label": "D", "text": "Formation of processus vaginalis", "correct": true}], "correct_answer": "D. Formation of processus vaginalis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Formation of processus vaginalis Formation of processus vaginalis precedes the descent of the testis into the scrotum, into which the testis invaginates. Processus vaginalis: A diverticulum of the peritoneal cavity that grows into the inguinal canal and scrotum. As the testis descends into the scrotum, it invaginates and processus vaginalis from behind. Once the descent of the testis is completed, the part of the processus vaginalis between the testis and the deep inguinal ring is obliterated. The part of processus vaginalis that covers the testis is now known as tunica vaginalis of testis.</p>\n<p><strong>Highyeild:</strong></p><p>Factors Responsible for Descent of Testis Differential Growth Of The Posterior Abdominal Wall. Formation of inguinal bursa Gubernaculum testis Processus vaginalis Increased intra-abdominal pressure helps to push the testis out of the abdomen. Male sex hormones greatly influence the descent of the testis. A specific neurotransmitter called calcitonin gene-related peptide is secreted by the genitofemoral nerve supplying the muscle fiber of the gubernaculum testis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. formation of gubernaculum, Option B. intraabdominal temperature and pressure, and Option C. maternal gonadotropins and male sex hormones, all help in the descent of the testis The temperature of the scrotum is slightly lesser than the body temperature for proper spermatogenesis.</p>\n<p><strong>Extraedge:</strong></p><p>When the testis descends into the scrotum from the posterior abdominal wall it carries vas deferens and blood vessels along with it. This provides an embryological basis for the ‘crossing of the vas deferens anterior to ureter near the urinary bladder.’</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are true about Cryptorchidism except:", "options": [{"label": "A", "text": "Testis may complete its descent after birth", "correct": false}, {"label": "B", "text": "Can be surgically corrected", "correct": false}, {"label": "C", "text": "Failure of spermatogenesis may occur", "correct": false}, {"label": "D", "text": "No risk of malignancy", "correct": true}], "correct_answer": "D. No risk of malignancy", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>No risk of malignancy There is an increased risk of malignancy in Cryptorchidism (undescended testis) So, orchidopexy should be performed at the desired age.</p>\n<p><strong>Highyeild:</strong></p><p>Cryptorchidism (undescended testis) It is a clinical condition in which one or both testes may fail to descend into the scrotum. In about 97% of newborns, the testes are present in the scrotum before birth; in remaining cases, the descent occurs postnatally during the first 3 months. Inlessthan1%ofinfantsoneorbothtestesfailtodescend. Cryptorchidism may occur due to decreased androgen (testosterone) production. The testes may become arrested at any point during their journey from the upper lumbar region of the abdominal cavity to the scrotum. Depending upon their location, the cryptorchidism is classified into four types Types of cryptorchidism according to location Type Location Lumbar Lumbar region of abdomen Iliac At deep inguinal ring Inguinal Within inguinal canal Pubic At superficial inguinal ring Scrotal High up in the scrotum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - All other statements are true about undescended testis -a) testis may complete its descent after birth ,b)can be surgically corrected and c) failure of spermatogenesis may occur.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical significance of cryptorchidism The undescended testes fail to produce mature spermatozoa due to higher abdominal temperature. In bilateral cryptorchidism the individual is sterile. The undescended testes are susceptible to injury. The undescended testes are likely to develop a malignancy. The undescended testes are likely to atrophy. In the case of cryptorchidism, testicular hormones are used to promote the descent. If it fails, the testes are surgically mobilized and fixed to the scrotal floor (orchidopexy).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about testicular descent except:", "options": [{"label": "A", "text": "Reaches iliac fossa by 3rd month", "correct": false}, {"label": "B", "text": "Reaches inguinal canal during 7th month", "correct": false}, {"label": "C", "text": "Reaches superficial inguinal ring by the 8th month", "correct": false}, {"label": "D", "text": "Reaches scrotum by 10th month", "correct": true}], "correct_answer": "D. Reaches scrotum by 10th month", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Reaches scrotum by 10th month Testis reaches scrotum by 9th month</p>\n<p><strong>Highyeild:</strong></p><p>Stages of descent of the testis Extent of descent Time Testis reaches iliac fossa During third month Reaches deep At the end of sixth month Inguinal ring Travels through inguinal canal Reaches at superficial inguinal ring Reaches scrotum During seventh month At eighth month By end of ninth month</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - All other options a) Reaches iliac fossa by 3rd month, b) Reaches inguinal canal during the 7th month and c) Reaches the superficial inguinal ring by the 8th month are true about the descent of the testis Failure of descent of the testes results in cryptorchidism.</p>\n<p><strong>Extraedge:</strong></p><p>Formation of inguinal bursa: An outpouching of various layers of the abdominal wall toward the scrotum. The cavity of the inguinal bursa forms the inguinal canal. Therefore inguinal bursa is formed before the testis enters into it.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Genital swellings in males differentiate into:", "options": [{"label": "A", "text": "Glans Penis", "correct": false}, {"label": "B", "text": "Penile urethra", "correct": false}, {"label": "C", "text": "The prepuce of the penis", "correct": false}, {"label": "D", "text": "Scrotum", "correct": true}], "correct_answer": "D. Scrotum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Scrotum Labioscrotal swellings differentiate into the labia majora or the scrotum, and the genital tubercle gives rise to the glans clitoris or glans penis. These are known as homologous organs in males and females. The genital swellings become visible on each side of the urethral folds. These swellings later form the scrotal swellings in the male and Labia majora in the female. At the end of the sixth week, however, it is impossible to distinguish between the two sexes.</p>\n<p><strong>Highyeild:</strong></p><p>Congenital anomalies of penis Agenesisofpenis(absence of penis):It occurs when the genital tubercle fails to develop. Micropenis (very small penis): It occurs due to underdevelopment of the genital tubercle. Bifid penis and double penis: The bifid penis occurs when the genital tubercle splits. The double penis is formed when the two genital tubercles develop.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Glans Penis The human penis and clitoris develop from the ambisexual genital tubercle. Option B. Penile urethra The penile part of the urethra (except the terminal part) is derived from the epithelium of the phallic part of the definitive urogenital sinus. Option C. Prepuce of the penis Development of prepuce of the penis : Close to the tip of the phallus a circular sulcus (coronary sulcus) appears, which separates the glans penis from the rest of the penis. The surface ectoderm covering the glans proliferates and grows inward forming a double-layered fold of ectoderm. Later, these two layers of ectoderm separate from each other to form the prepuce.</p>\n<p><strong>Extraedge:</strong></p><p>Congenital anomalies of the prepuce (foreskin) Phimosis: The prepuce is a fold of skin covering the glans of the penis. It develops during the 12th week of IUL. It remains adherent to the glans up to 3 years of age and is not easy to retract. Thereafter it separates progressively from the glans and is non-adherent by 6 years of age. Phimosis is a condition in which the prepuce is so tight that it cannot be retracted fully from the glans. It is usually congenital and is often associated with pinhole meatus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Uterus develops from:", "options": [{"label": "A", "text": "Mullerian Duct", "correct": true}, {"label": "B", "text": "Wolffian duct", "correct": false}, {"label": "C", "text": "Both", "correct": false}, {"label": "D", "text": "None", "correct": false}], "correct_answer": "A. Mullerian Duct", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Mullerian Duct The Mullerian ducts are the primordial anlage of the female reproductive tract. They differentiate to form the fallopian tubes, the uterus, the uterine cervix, and the superior aspect of the vagina.</p>\n<p><strong>Highyeild:</strong></p><p>The Mullerian duct (MD) is the embryonic structure that develops into the female reproductive tract (FRT), including the oviduct, uterus, cervix and upper vagina .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Wolffian duct Wolffian ducts (WDs) are the embryonic structures that form the male internal genitalia. Option C. Both Option D. None Therefore Options B, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Following is the list of the development of various organs from their embryonic parts: table,tr,th,td {border:1px solid black;} Gonad Testis Ovary Gubernacular cord Gubernaculum testis Ovarian and round ligaments Mesonephros (Wolffian body) Appendix epididymis (?) Appendices vesiculosae (?) Efferent ductules Epoophoron Lobules of epididymis Paradidymis Paroophoron Aberrant ductules Mesonephric duct (Wolffian duct) Duct of epididymis Duct of epoophoron (Gartner's duct) Ductus (vas) deferens Ejaculatory duct Part of bladder and prostatic urethra Part of bladder and urethra Paramesonephric (Müllerian) duct Appendix testis Uterine tube Uterus Prostatic utricle Vagina (?) Allantoic duct Urachus Urachus Cloaca: Dorsal part Rectum and upper part of anal canal Rectum and upper part of anal canal Ventral part Most of bladder Most of bladder and urethra Part of prostatic urethra Urogenital sinus Prostatic urethra distal to utricle Bulbourethral glands Greater vestibular glands Rest of urethra to glans Vestibule Genital folds Ventral penis Labia minora Genital tubercle Penis Clitoris Urethra in glans</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Regarding the development of the genital system. Which is an incorrect statement.", "options": [{"label": "A", "text": "Ovaries develop in the absence of Y chromosomes", "correct": false}, {"label": "B", "text": "Genital ridge develops at 5th week", "correct": false}, {"label": "C", "text": "The interstitial or Leydig cells secrete testosterone by eight weeks of IUL.", "correct": false}, {"label": "D", "text": "The differentiation of the gonadal ridge into a testis is a slow phenomenon, in contrast to the development of the ovary.", "correct": true}], "correct_answer": "D. The differentiation of the gonadal ridge into a testis is a slow phenomenon, in contrast to the development of the ovary.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The differentiation of the gonadal ridge into a testis is a slow phenomenon, in contrast to the development of the ovary. The differentiation of the gonadal ridge into a testis is a rapid phenomenon, which contrasts with the slow and late development of the ovary. Testicular tissues, and in particular seminiferous tubules, are recognized in the human embryo at 7 weeks of fetal age. Orientation of the primordial gonad towards ovarian differentiation in XX subjects appears after the 2 nd month of fetal age.</p>\n<p><strong>Highyeild:</strong></p><p>Male and female homologs derived from an undifferentiated genital system Indifferent gonad Testis Ovary Primordial germ cells Spermatozoa Ova Cortex-sex cords Seminiferous tubules (spermatogonia and Sertoli cells) Ovarian follicles Medulla Rete testis Rete ovarii Mesonephric tubules Ductuli efferentes (vasa efferentia) Epoophoron Paradidymis Paroophoron Mesonephric (Wolffian) duct Appendix of epididymis Appendix of ovary Epididymis Duct of epoophoron Ductus deferens Ejaculatory ducts Seminal vesicle Ureter, pelvis, calyces and collecting tubules Paramesonephric (Müllerian) ducts Appendix of testis (hydatid of Morgagni) Paratubal cyst Uterine tube Prostatic utricle Uterus Upper part of vagina</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Ovaries develop in the absence of Y chromosomes The presence of the Sry gene, (Sex-determining Region of the Y chromosome), on the Y chromosome directs the gonadal primordia to form a testis. Ovaries arise in the absence of the Sry gene. Option B. Genital ridge develops in 5th week Gonads appear initially as a pair of longitudinal genital or gonadal ridges at the 4–5th week . Primitive gonads are formed by the proliferation of germ cells, which migrate from the yolk sac and undergo condensation of the underlying mesenchyme in the sixth week . Option C . The interstitial or Leydig cells secrete testosterone by eight weeks of IUL. The interstitial or Leydig cells secrete testosterone by eight weeks of IUL, Which is critical for the male sexual differentiation of the internal and external genitalia.</p>\n<p><strong>Extraedge:</strong></p><p>The development of external genitalia is similar in both males and females till the sixth week of IUL (indifferent stage) .After this stage the development proceeds either in a male or female direction under the influence of hormones</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Structures that act as a temporary set of kidneys in the fetus during development?", "options": [{"label": "A", "text": "Mesonephros", "correct": true}, {"label": "B", "text": "Metanephros", "correct": false}, {"label": "C", "text": "Paramesonephric ducts", "correct": false}, {"label": "D", "text": "Pronephros", "correct": false}], "correct_answer": "A. Mesonephros", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Mesonephros The second set of mesonephros appear late in the fourth week and are functional until the permanent kidneys or metanephros are fully developed. During development, three sets of kidneys are formed in the embryo . Metanephros mainly form adult kidneys and nephrons .</p>\n<p><strong>Highyeild:</strong></p><p>The sequence of events of the pronephros, mesonephros, and metanephros Nephrogenic cord/tissue Location Segmentation Time of appearance Functional status Duct Pronephros Cervical region Segmented Beginning of the fourth week Nonfunctional/disappears Pronephric duct persists Mesonephros Thoracolumbar region Segmented End of the fourth week Functional for a short period then disappears, except for its caudal excretory tubules Mesonephric duct persists Metanephros Sacral region Nonsegmented Beginning of the third month Functional Ureter</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Metanephros . Metanephros mainly form adult kidneys and nephrons . Option: D. The first set of pronephros (choice D) are transitional, nonfunctional structures that appear around the fourth week of development. Next, comes the mesonephros, then the permanent set of kidneys develops from the metanephros. Option: C. The paramesonephric ducts (choice C) are structures developing lateral to the gonads and mesonephric ducts. They play an essential role in the female reproductive system but are not involved in the formation of the kidneys. The ureteric bud is an outgrowth from the mesonephric duct that gives rise to the ureter, renal pelvis, calyces, and collecting tubules.</p>\n<p><strong>Extraedge:</strong></p><p>Ascent of Kidney At first, the permanent kidney (derived from meta neph- ros) lies in the sacral region . Later due to differential growth of the posterior abdominal wall and reduction of fetal curvature the kidney ascends to reach the thoracic-lumbar region (T12–L3 vertebral levels). The ureter elongates accordingly as the kidney ascends.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A female patient is diagnosed by sonogram with uterus didelphys (double uterus). The imaging study reveals a bicornuate uterus with a single vagina. During development, the uterus develops from which of the following?", "options": [{"label": "A", "text": "Mesonephric Ducts", "correct": false}, {"label": "B", "text": "Nephrogenic ridge", "correct": false}, {"label": "C", "text": "Paramesonephric ducts", "correct": true}, {"label": "D", "text": "Urogenital sinus", "correct": false}], "correct_answer": "C. Paramesonephric ducts", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Paramesonephric ducts During development, the uterus develops from fusion of the caudal ends of the paramesonephric ducts . Paramesonephric ducts are also known as Mullerian ducts . Failure of fusion results in uterus didelphys.</p>\n<p><strong>Highyeild:</strong></p><p>The uterus may be slightly indented in the middle and is known as an arcuate uterus . The uterus and vagina both may be separated into two and is known as a sub-septate uterus .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The mesonephric ducts give rise to the epididymis, vas deferens, and ejaculatory duct in the male. Option: B. The nephrogenic ridge is the derivative of the urogenital ridge which will give rise to the urinary system. Option: D. The urogenital sinus gives rise to the urinary bladder, urethra, vagina, and associated glands in the female. The yolk sac plays a role in the transfer of nutrients before uteroplacental circulation is established, in blood development before the liver begins its hematopoietic activity , and is the site of the formation of primordial germ cells .</p>\n<p><strong>Extraedge:</strong></p><p>The uterus is in two horns, the cervix is separated and the vagina is single and is known as uterus bicornis and bicolis .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 3-year-old male child is admitted to the pediatric clinic. His diagnosis reveals that the intermediate portion of the processus vaginalis is not obliterated. Which of the following conditions will most likely result from this?", "options": [{"label": "A", "text": "Hypospadias", "correct": false}, {"label": "B", "text": "Sterility", "correct": false}, {"label": "C", "text": "Congenital hydrocele", "correct": true}, {"label": "D", "text": "Ectopic testis", "correct": false}], "correct_answer": "C. Congenital hydrocele", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Congenital hydrocele The distal portion of the processus vaginalis contributes to the tunica vaginalis which is related to the testis. If an intermediate portion of the processus vaginalis persists, it often fills with fluid, creating a hydrocele . If the entire processus vaginalis persists, the patient is likely to develop a congenital inguinal hernia. Congenital hydrocele is usually repaired by herniotomy.</p>\n<p><strong>Highyeild:</strong></p><p>Types of hypospadias : Depending upon the location of (EUO) external urethral orifice, the hypospadias is classified into the following five types. Glandular: When the EUO is located on the ventral aspect of the glans. Coronal/balance: When the urethra opens at the base of the glans penis. In this case, the glans are often grooved on its ventral aspect. Penile: When the urethra opens anywhere between the base of the glans and in front of the scrotum. Penoscrotal: When the urethra opens at the junction of the penis and scrotum. Perineal: When a wide sagittal slit is found along the entire length of the penis and scrotum. The two scrotal swellings closely resemble labia majora.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Hypospadias Hypospadias: It is the commonest congenital anomaly of the urethra (occurring in 3–5/100 births). In this condition, the external urethral orifice (EUO) is located on the ventral aspect of the penis, instead of at the tip of the penis. It occurs due to failure of canalization of the ectodermal cord in the glans and/or failure of fusion of the urethral folds. Usually, the penis is underdeveloped and curved ventrally, producing a clinical condition called chordae . Option B. Sterility Male infertility can be caused by low sperm production, abnormal sperm function, or blockages that prevent the delivery of sperm. Illnesses, injuries, chronic health problems, lifestyle choices, and other factors may contribute to male infertility. Option D. Ectopic testis An ectopic testis is one that is located in an aberrant position off the path of normal descent. The most common site of palpable ectopia is the superficial inguinal pouch of Denis-Browne, located between Scarpa's fascia and the external oblique fascia above the external inguinal ring.</p>\n<p><strong>Extraedge:</strong></p><p>Epispadias : In this condition, the urethral orifice is located on the dorsal aspect of the penis. It is a rare anomaly and occurs in 1/30,000 births. Although epispadias may occur as an isolated defect, it is mostly associated with exstrophy of the urinary bladder (ectopia vesicae). The exact embryological basis for this condition is not clear. Probably it occurs when the genital tubercle instead of being formed cranial to the cloacal membrane is formed more dorsally in the region of anorectal septum, and thus part of the urogenital membrane is seen cranial to the genital tubercle. When this membrane ruptures then the uro- genital sinus opens on the dorsal aspect of the penis and then the urethral groove extends on the dorsal aspect of the penis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Testicles are absent from the scrotum of a 1-year-old male admitted to the pediatric clinic. The pediatrician examined the infant and palpated the testes in the inguinal canal. Which of the following terms is used to describe this condition?", "options": [{"label": "A", "text": "Pseudohermaphroditism", "correct": false}, {"label": "B", "text": "True hermaphroditism", "correct": false}, {"label": "C", "text": "Cryptorchism", "correct": true}, {"label": "D", "text": "Congenital adrenal hyperplasia", "correct": false}], "correct_answer": "C. Cryptorchism", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cryptorchism Cryptorchism, often called an undescended testis, is the result of incomplete migration of the gonad from the abdomen to a location in the scrotum where it is exposed to temperatures slightly lower than core body temperature. It can increase the risk of malignancy in undescended testis. This is important for spermatogenesis and testicular function. A testis that cannot be surgically relocated into the scrotum is usually removed because it would otherwise be prone to develop testicular cancer</p>\n<p><strong>Highyeild:</strong></p><p>Anomalies of descent (cryptorchidism): Descent of the testis may fail to occur, or may be incomplete. The organ may lie in the lumbar region, in the iliac fossa, in the inguinal canal, or in the upper part of the scrotum. Some interesting facts about this condition are as follows: The testis may complete its descent after birth. Spermatogenesis often fails to occur in an undescended testis. An undescended testis is more likely to develop a malignant tumor than a normal testis. The condition can be surgically corrected.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A . Pseudohermaphroditism Pseudohermaphroditism Gonads are of one sex, while genitalia (internal, external or both) are of opposite sex. A patient having a testis is described as a male hermaphrodite; and one having an ovary is described as a female hermaphrodite. Female pseudohermaphroditism is caused by excess of androgens produced by the fetal suprarenal gland (adrenogenital syndrome). It may also be caused by administration of progestins to the mother during pregnancy. Option B. True hermaphroditism True hermaphroditism The person has at least one testis and one ovary in the body. The external genitalia may be male, or female, or midway between the two. The chromosomal sex may be either male or female. Option D. Congenital adrenal hyperplasia Congenital adrenal hyperplasia (CAH) refers to a group of genetic disorders that affect the adrenal glands, a pair of walnut-sized organs above the kidneys. The adrenal glands produce important hormones, including Cortisol, which regulates the body's response to illness or stress.</p>\n<p><strong>Extraedge:</strong></p><p>Congenital adrenal hyperplasia (CAH) refers to a group of genetic disorders that affect the adrenal glands, a pair of walnut-sized organs above the kidneys. The adrenal glands produce important hormones, including Cortisol, which regulates the body's response to illness or stress. Congenital anomalies of the penis Agenesis of the penis(absence of penis): It occurs when the genital tubercle fails to develop. Micropenis (very small penis): It occurs due to the underdevelopment of the genital tubercle. Bifid penis and double penis: The bifid penis occurs when the genital tubercle splits. The double penis is formed when the two genital tubercles develop.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 25 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which of the following structures does not pass through the superior thoracic aperture?", "options": [{"label": "A", "text": "Right Vagus", "correct": false}, {"label": "B", "text": "Brachiocephalic artery", "correct": false}, {"label": "C", "text": "Thoracic duct", "correct": false}, {"label": "D", "text": "Right recurrent laryngeal nerve", "correct": true}], "correct_answer": "D. Right recurrent laryngeal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right recurrent laryngeal nerve The left (not right) recurrent laryngeal nerve passes through the superior thoracic aperture. The right recurrent laryngeal nerve hooks around the right subclavian artery in the neck region and ascends in the tracheoesophageal groove to supply the larynx.</p>\n<p><strong>Highyeild:</strong></p><p>The superior thoracic aperture is kidney-shaped and lies in an oblique transverse plane tilted anteroinferior to posterosuperior. It is roughly 10 cm in transverse dimension and 5 cm in AP dimension. Boundaries Posteriorly: T1 vertebral body and costovertebral joints Laterally: first ribs and their costal cartilage Anteriorly: superior border of the manubrium Structures passing through Superior Thoracic aperture</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Right Vagus Option B. Brachiocephalic artery Option C. Thoracic duct The right vagus nerve, Brachiocephalic artery, and Thoracic duct pass through the inlet of the thorax.</p>\n<p><strong>Extraedge:</strong></p><p>Structures passing through the superior thoracic aperture can be divided into five groups: midline, bilateral, posteriorly, and asymmetric left and right. Midline from anterior to posterior sternohyoid and sternothyroid muscles thymic remnants inferior thyroid veins trachea trachea-oesophageal sulcus containing recurrent laryngeal nerves esophagus thoracic duct displaced to the left longus colli muscles anterior longitudinal ligament Laterally on both sides Sibson's fascia internal thoracic artery Posteriorly from medial to lateral sympathetic trunk supreme intercostal vein superior intercostal artery the ventral ramus of the first thoracic nerve On the left: left common carotid artery left subclavian artery the left vagus nerve, between the left common carotid and left subclavian arteries left brachiocephalic vein left phrenic nerve On the right brachiocephalic trunk the right vagus nerve, lateral to the brachiocephalic trunk right brachiocephalic vein the right phrenic nerve, lateral to the right brachiocephalic vein</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Compression of the cervical rib can cause: Thenar hypertrophy Neurovascular symptom Raynaud's phenomenon C8; T1 paresthesia Select the correct answer from given below code:", "options": [{"label": "A", "text": "1,2,3,4.", "correct": false}, {"label": "B", "text": "1,3,4.", "correct": false}, {"label": "C", "text": "2,3,4.", "correct": true}, {"label": "D", "text": "2,3", "correct": false}], "correct_answer": "C. 2,3,4.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2,3,4. A cervical rib is a rib attached to vertebra C7. It occurs in about 5% of subjects and may lead to thoracic outlet syndrome. The cervical rib may exert traction on the lower trunk of the brachial plexus, which arches over a cervical rib. Such a person c omplains of paresthesia or abnormal sensations along the ulnar border of the forearm and wasting of the small muscles of the hand supplied by segment T1. Vascular changes may also occur, resulting in Raynaud's phenomenon. Compression of the sympathetic chain may cause Horner's syndrome.</p>\n<p><strong>Highyeild:</strong></p><p>The presence of a cervical rib can cause a form of thoracic outlet syndrome due to compression of the lower trunk of the brachial plexus or subclavian artery. These structures become infringed upon by the cervical rib and scalene muscles. Compression of the brachial plexus may be identified by weakness of the muscles in the hand near the base of the thumb.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. 1,2,3,4. Option B. 1,3,4. Option D. 2,3. Thenar muscles are supplied by the median nerve, not the ulnar nerve. In thoracic outlet syndrome, the median nerve is not involved.</p>\n<p><strong>Extraedge:</strong></p><p>Compression of the subclavian artery is often diagnosed by finding a positive Adson's sign on examination, where the radial pulse in the arm is lost during abduction and external rotation of the shoulder. A positive Adson's sign is non-specific for the presence of a cervical rib. However, many individuals without a cervical rib will have a positive test. Compression of the sympathetic chain may cause Horner's syndrome.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about the attachment of supra pleural membrane: Attached to clavicle Attached to 2nd rib and its costal cartilage Attached to 1st rib and its costal cartilage Connected to the junction of manubrium and body of sternum Attached to tip of the transverse process of the 7th cervical vertebrae Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,3,5", "correct": false}, {"label": "B", "text": "1,2,3", "correct": false}, {"label": "C", "text": "2,3,4", "correct": false}, {"label": "D", "text": "3,5", "correct": true}], "correct_answer": "D. 3,5", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>3,5 Sibson’s fascia, or subpleural membrane, separates the thorax from the neck. The membrane is triangular. Its apex is attached to the tip of the transverse process of the seventh cervical vertebra and the base to the inner border of the first rib and its cartilage. Sibson’s fascia</p>\n<p><strong>Highyeild:</strong></p><p>Morphologically, Sibson’s fascia is regarded as the flattened tendon of the scalenus minimus (pleuritis) muscle. It is thus formed by scalenus minimus and endo thoracic fascia. Functionally, it provides rigidity to the thoracic inlet so that the root of the neck is not puffed up and down during respiration.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. 1,3,5 Option B. 1,2,3 Option C. 2,3,4 Options A, B, and C are incorrect because Sibson’s fascia is not attached to the clavicle, 2nd rib, and its costal cartilage and junction of manubrium and body of the sternum.</p>\n<p><strong>Extraedge:</strong></p><p>The inferior surface of the membrane is fused to the cervical pleura, beneath which lies the apex of the lung. Its superior surface is related to the subclavian vessels and other structures at the root of the neck.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are true about Sibson's fascia except:", "options": [{"label": "A", "text": "The modified inner part of scalenus anterior", "correct": true}, {"label": "B", "text": "Attached to the inner of the first rib", "correct": false}, {"label": "C", "text": "Covers the supraclavicular region of the lung", "correct": false}, {"label": "D", "text": "Attached is the transverse process of C-7", "correct": false}], "correct_answer": "A. The modified inner part of scalenus anterior", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The modified inner part of scalenus anterior Morphologically, Sibson’s fascia is regarded as the flattened tendon of the scalenus minimus (pleuritis) muscle. It is thus formed by scalenus minimus and endo thoracic fascia.</p>\n<p><strong>Highyeild:</strong></p><p>Superiorly, the Suprapleural membrane receives muscle fibers from some of the deep muscles in the neck (scalene muscles) that keep the membrane taught. The subpleural membrane provides apical support for the pleural cavity in the root of the neck.</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options :- Options B & D: Its apex is attached to the tip of the transverse process of the seventh cervical vertebra and the base to the inner border of the first rib and its cartilage. Option C: The inferior surface of the membrane is fused to the cervical pleura, beneath which lies the apex of the lung. Sibson’s fascia, or supra pleural membrane, separates the thorax from the neck. The membrane is triangular. Morphologically, Sibson’s fascia is regarded as the flattened tendon of the scalenus minimus (pleuritis) muscle. It is thus formed by scalenus minimus and endo thoracic fascia.</p>\n<p><strong>Extraedge:</strong></p><p>Functionally, Sibson’s fascia provides rigidity to the thoracic inlet so that the root of the neck is not puffed up and down during respiration. Its superior surface is related to the subclavian vessels and other structures at the root of the neck.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statements is false about the diaphragm?", "options": [{"label": "A", "text": "The left side pushed down my heart", "correct": false}, {"label": "B", "text": "The left side is lower than the right", "correct": false}, {"label": "C", "text": "The right side pushed up by the liver", "correct": false}, {"label": "D", "text": "The right side is lower than the left", "correct": true}], "correct_answer": "D. The right side is lower than the left", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The right side is lower than the left Muscle fibers of the diaphragm arch upwards and inwards to form the right and left domes. The right dome is higher than the left dome. In full expiration, it reaches the level of the fourth intercostal space while the left crown reaches the fifth rib. Right and Left domes of Diaphragm</p>\n<p><strong>Highyeild:</strong></p><p>The stomach is frequently visible as a gas-filled bubble below the left hemidiaphragm. It is essential to be aware that the lowest portion of the lungs, which occupy the posterior costophrenic recesses, extend below the level of the contours of the hemidiaphragm. The stomach bubble forms a window through which this part of the lung is visible on the left.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect Options :- Option A. Left side pushed down my heart. The stomach and spleen are immediately inferior to the left hemidiaphragm, so it is slightly pushed down. Option B. Left side lower than the right Option B: The right dome is higher than the left dome. In full expiration, it reaches the level of the fourth intercostal space while the left crown reaches the fifth rib. The central tendon lies at the level of the lower end of the sternum at the 6th costal cartilage . Option C. Right side pushed up by the liver. Option C: The downward concavity of the dome is occupied by the liver on the right side and by the fundus of the stomach on the left side. The medial fibers of the right crus run upwards and to the left and encircle the esophagus. In general, all fibers converge towards the central tendon for their insertion.</p>\n<p><strong>Extraedge:</strong></p><p>Elevated Hemidiaphragm Approach of Patient</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following structures passes through the aortic opening of the diaphragm?", "options": [{"label": "A", "text": "Lymphatics of Liver", "correct": false}, {"label": "B", "text": "vagus nerve", "correct": false}, {"label": "C", "text": "azygos vein", "correct": true}, {"label": "D", "text": "inferior vena cava", "correct": false}], "correct_answer": "C. azygos vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>azygos vein The aortic opening: It lies at the lower border of the 12th thoracic vertebra. It transmits: Aorta Thoracic duct Azygos vein</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Lymphatics of Liver Option D. inferior vena cava Vena cava opening lies in the central tendon of the diaphragm at the level of the 8th thoracic vertebra. It transmits: The inferior vena cava (Option D) Branches of the right phrenic nerve. Lymphatics of the (Option A) Option B. vagus nerve The esophageal opening lies in the muscular part of the diaphragm, at the level of the 10th thoracic vertebrae It transmits: Oesophagus Gastric or vagus nerves (Option B) Esophageal branches of the left gastric artery, with some esophageal veins accompanying the arteries.</p>\n<p><strong>Extraedge:</strong></p><p>Small Openings in the Diaphragm The greater and lesser splanchnic nerves pierce each crus of the diaphragm. The left crus is stabbed in addition to the hemiazygos vein. The sympathetic chain passes from the thorax to the abdomen behind the medial arcuate ligament or medial lumbocostal arch. The subcostal nerve and vessels pass behind the lateral arcuate ligament or lumbocostal arch. The superior epigastric vessels and some lymphatics pass between the origins of the diaphragm from the xiphoid process and the 7th costal cartilage. This gap is known as Larry’s space or foramen of Morgagni. The musculophrenic vessels pierce the diaphragm at the level of the 9th costal cartilage. Intercostal nerves and vessels pass through the interdigitating slips of the diaphragm and transversus abdominis muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The BASE of the heart is formed by:", "options": [{"label": "A", "text": "Left Atrium", "correct": true}, {"label": "B", "text": "Right atrium", "correct": false}, {"label": "C", "text": "Left ventricle", "correct": false}, {"label": "D", "text": "Right ventricle", "correct": false}], "correct_answer": "A. Left Atrium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left Atrium The heart has: An apex is directed downwards, forwards, and to the left. A base (posterior surface) directed backward Three characters—anterior/sternocostal, inferior, and left lateral Borders: The covers are demarcated by upper, right, and left walls. The base of the heart is also called its posterior surface. It is formed mainly by the left atrium and by a small part of the right atrium. About the base, one can see the openings of four pulmonary veins, which open into the left atrium, and the superior and inferior vena cava, which extend into the right atrium. External features of the heart from the posterior aspect</p>\n<p><strong>Highyeild:</strong></p><p>The base of the heart ( basis cordis ), directed upward, backward, and to the right, is separated from the fifth, sixth, seventh, and eighth thoracic vertebræ by the esophagus, aorta, and thoracic duct.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Right atrium The right atrium and ventricle comprise most of the heart's sternocostal surface. Option C. Left ventricle Option D. Right ventricle The diaphragmatic surface is made up of the right and left ventricles.</p>\n<p><strong>Extraedge:</strong></p><p>A pex (the most inferior, anterior, and lateral part of the heart) is medial to the midclavicular line in the left fifth intercostal space. The left ventricle forms it. The apex of the heart is the lowest superficial part of the heart. It is directed downward, forward, and to the left, overlapped by the left lung and pleura.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about atrioventricular groove are all except:", "options": [{"label": "A", "text": "Contains left anterior descending coronary artery", "correct": true}, {"label": "B", "text": "Also called a coronary sulcus", "correct": false}, {"label": "C", "text": "It contains the right coronary artery", "correct": false}, {"label": "D", "text": "Has circumflex branch of left coronary artery", "correct": false}], "correct_answer": "A. Contains left anterior descending coronary artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Contains left anterior descending coronary artery The left anterior descending artery first passes posterior to the pulmonary artery, then passes anterior ward between that pulmonary artery and the left atrium to reach the anterior interventricular sulcus, which descends to the notch of the cardiac apex. In 78% of cases, it gets the height of the heart.</p>\n<p><strong>Highyeild:</strong></p><p>The left anterior descending artery is a branch of the left coronary artery . It supplies the anterior portion of the left ventricle . It provides about half of the arterial supply to the left ventricle and is thus considered an essential vessel supplying the left ventricle. Blockage of this artery is often called widow-maker infarction due to a high risk of death. Atrioventricular groove/Coronary sulcus of heart</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B: The atria are separated from the ventricles by a circular atrioventricular or coronary sulcus divided into anterior and posterior parts. Options C & D: Anterior part consists of right and left halves. The right half is oblique between the right auricle and right ventricle, lodging the right coronary artery. The left part is small between the left auricle and left ventricle, lodging a circumflex branch of the left coronary artery. The ascending aorta and the pulmonary trunk overlaps the coronary sulcus anteriorly. The interatrial groove is faintly visible posteriorly, while anteriorly, it is hidden by the aorta.</p>\n<p><strong>Extraedge:</strong></p><p>The coronary sulcus, separating the atria and ventricles, spans from the upper medial end of the third left costal cartilage to the middle of the right sixth chondrosternal joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The wrong statement about the right atrium is: Auricle is covered true of ascending aorta AV node is present in muscular interventricular septum Crista terminalis divides the right atrium into 2 parts The coronary sinus is present in part of the atrioventricular groove. Select the correct answer from given below code:", "options": [{"label": "A", "text": "1,2,3,4", "correct": false}, {"label": "B", "text": "2,3", "correct": false}, {"label": "C", "text": "2", "correct": true}, {"label": "D", "text": "1,4", "correct": false}], "correct_answer": "C. 2", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2 Only statement 2 needs to be corrected regarding the anatomy of the heart. Options explanation Statement 1: The upper end is prolonged to the left to form the right auricle. The auricle covers the root of the ascending aorta and partly overlaps the infundibulum of the right ventricle. Its margins are notched, and the interior is sponge-like, which prevents the free flow of blood. Statement 2: The AV node is present in the triangle of Koch in the atrioventricular septum. Statement 3: Along the right border of the atrium, a shallow vertical groove passes from the superior vena cava to the inferior vena cava. This groove is called the sulcus terminalis. It is produced by an internal muscular ridge called the crista terminalis. The upper part of the sulcus contains the sinoatrial or SA node, which acts as the pacemaker of the heart, Statement 4: coronary sinus is present in the coronary sulcus in the atrioventricular groove.</p>\n<p><strong>Highyeild:</strong></p><p>The right atrium receives and holds deoxygenated blood from the superior vena cava, inferior vena cava, anterior cardiac veins, most minor cardiac veins, and the coronary sinus, which it then sends down to the right ventricle (through the tricuspid valve), which turn sends it to the pulmonary artery for pulmonary circulation. Interior of Right Atrium</p>\n<p><strong>Extraedge:</strong></p><p>The sinoatrial (SA) node is located in the posterior aspect of the right atrium, next to the superior vena cava. This is a group of pacemaker cells that spontaneously depolarize to create an action potential. The cardiac action potential then spreads across both atria, causing them to contract, forcing the blood they hold into their corresponding ventricles.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Trabeculae carneae are present in:", "options": [{"label": "A", "text": "Left Atrium", "correct": false}, {"label": "B", "text": "Right ventricle", "correct": false}, {"label": "C", "text": "Left ventricle", "correct": false}, {"label": "D", "text": "Both B and C", "correct": true}], "correct_answer": "D. Both B and C", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Both B and C Trabeculae carnage is rounded or irregular muscular columns that project from the inner surface of the right and left ventricles of the heart. These are different from the pectinate muscles, which are present in the heart's atria. In development, trabeculae carnage are among the first cardiac structures to develop in the embryonic cardiac tube.</p>\n<p><strong>Highyeild:</strong></p><p>The walls of the inflow portion of the right ventricle have numerous muscular, irregular structures called trabeculae carneae. Most of these are either attached to the ventricular walls throughout their length, forming ridges or creating bridges at both ends. A few trabeculae carnage (papillary muscles) have only one end attached to the ventricular surface, while the other end is the point of attachment for tendon-like fibrous cords (the chordae tendineae), which connect to the free edges of the cusps of the tricuspid valve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Left Atrium The pectinate muscles ( musculi pectinati ) are parallel muscular ridges in the walls of the atria of the heart. Option B. Right ventricle Option C. Left ventricle Trabeculae carnage is rounded or irregular muscular columns that project from the inner surface of the right and left ventricle of the heart, so both the Right and left ventricle are the correct answer (Option-D).</p>\n<p><strong>Extraedge:</strong></p><p>There are three papillary muscles in the right ventricle The anterior papillary muscle is the most significant and constant papillary muscle and arises from the anterior wall of the ventricle. The posterior papillary muscle may consist of one, two, or three structures, with some chordae tendineae arising directly from the ventricular wall. The septal papillary muscle is the most inconsistent, either small or absent, with chordae tendineae emerging directly from the septal wall. There are three papillary muscles in the right ventricle The trabeculae carnage in the left ventricle is fine and delicate compared to those in the right ventricle. The anterior and posterior papillary muscles are usually found in the left ventricle and are larger than those of the right ventricle. Trabeculae carneae of Right and Left Ventricle</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which one of the following statements is not true about the right atrium", "options": [{"label": "A", "text": "Fossa ovalis represent a remnant of foramen ovale", "correct": false}, {"label": "B", "text": "The anterior and posterior parts are divided by crista terminalis", "correct": false}, {"label": "C", "text": "The anterior portion is derived from the absorption of the right horn of sinus venosus", "correct": true}, {"label": "D", "text": "The rear part is smooth", "correct": false}], "correct_answer": "C. The anterior portion is derived from the absorption of the right horn of sinus venosus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The anterior portion is derived from the absorption of the right horn of sinus venosus The posterior part of the right atrium is derived embryologically from the right horn of the sinus venosus. The anterior part of the right atrium, including the right auricle, is sometimes referred to as the atrium proper. This terminology is based on its origin in the embryonic primitive atrium . Its walls are covered by ridges called the musculi pectinate (pectinate muscles), which fan out from the crista like the \"teeth of a comb.\"</p>\n<p><strong>Highyeild:</strong></p><p>An additional structure in the right atrium is the opening of the coronary sinus, which receives blood from most of the cardiac veins and opens medially to the beginning of the inferior vena cava.</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options :- Option A: The interatrial septum has an opening in the right atrium, the foramen ovale, which provides access to the left atrium; this connects the two chambers, which is essential for fetal blood circulation. a foramen ovale is no longer needed and closes to leave a depression (the fossa ovalis) in the atrial wall. The annulus ovalis or limbus fossa ovalis is the prominent margin of the fossa ovalis. It represents the lower free edge of the septum secundum. Option B: Along the right border of the atrium, there is a shallow vertical groove that passes from the superior vena cava to the inferior vena cava. This groove is called the sulcus terminalis. It is produced by an internal muscular ridge called the crista terminalis. Option D: The posterior part of the right atrium is termed the sinus venarum; it also includes most of the lateral wall of the chamber. It has a relatively smooth surface compared to the anterior part. The posterior and anterior walls merge at the crista terminalis.</p>\n<p><strong>Extraedge:</strong></p><p>The fossa ovalis marks the location of the embryonic foramen ovale, which is an essential part of fetal circulation. The foramen ovale allows oxygenated blood to enter the right atrium through the inferior vena cava to pass directly to the left atrium and bypass the lungs, which are nonfunctional before birth.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following are tributaries of the right atrium except.", "options": [{"label": "A", "text": "Superior Vena Cava", "correct": false}, {"label": "B", "text": "Coronary sinus", "correct": false}, {"label": "C", "text": "Thebesian veins", "correct": false}, {"label": "D", "text": "Bronchial veins", "correct": true}], "correct_answer": "D. Bronchial veins", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Bronchial veins The bronchial veins are small vessels that return blood from the larger bronchi and structures at the roots of the lungs. The right side drains into the azygos vein, while the left side drains into the left superior intercostal or accessory hemiazygos vein. Bronchial veins are part of the bronchial circulation, carrying waste products away from the cells that constitute the lungs.</p>\n<p><strong>Highyeild:</strong></p><p>Tributaries or Inlets of the Right Atrium Openings of the Right Atrium SVC opening superiorly superiorly to the right of the crista IVC opening inferiorly guarded by a ridge that extends from the anterior lip of IVC (remains of the valve of IVC / Eustachian valve) coronary sinus opening inferiorly medial to the IVC opening in the posterior wall of the right atrium bordered by a slight fold (valve of coronary sinus / the Asian valve) Anterior cardiac vein Venae cordis minimal</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Superior Vena Cava The superior vena cava is formed by the left and right brachiocephalic veins, behind the lower border of the first right costal cartilage. It passes vertically downward behind the first intercostal space. It receives an azygos vein just before it pierces the fibrous pericardium opposite the right second costal cartilage, and its lower part is intrapericardial. And then, it ends in the upper and posterior part of the sinus venarum of the right atrium, at the upper right front portion of the heart. Option B. Coronary sinus The coronary sinus is located in the posterior portion of the coronary sulcus on the diaphragmatic or rear surface of the heart. The coronary sinus empties directly into the right atrium near the conjunction of the posterior interventricular sulcus and the coronary sulcus (crux cordis area), located between the inferior vena cava and tricuspid valve; this atrial ostium can be partially covered by Thebesian valve, although the anatomy of this valve is highly variable. Option C. Thebesian veins The Thebesian valve is a caudal remnant of the embryonic sinoatrial valve. It is usually a semicircular fold of membrane in the right atrium at the orifice of the coronary sinus. It is on the posterior, inferior heart surface, medial to the low vena cava opening.</p>\n<p><strong>Extraedge:</strong></p><p>Numerous venous tributaries are traversing the surface of the heart. Eventually, they merge to form the coronary sinus, which drains indirectly into the right atrium. The Anterior cardiac and Thebesian (small) veins drain directly into the cardiac chambers.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The boundary of the triangle of Koch is not formed by", "options": [{"label": "A", "text": "Tricuspid Valve", "correct": false}, {"label": "B", "text": "Tendon of Todaro", "correct": false}, {"label": "C", "text": "Limbus fossa ovalis", "correct": true}, {"label": "D", "text": "Coronary sinus", "correct": false}], "correct_answer": "C. Limbus fossa ovalis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Limbus fossa ovalis The limbus fossa ovalis ( annulus ovalis ) is the prominent oval margin of the fossa ovalis. It is most distinct above and at the sides of the fossa ovalis; below, it is deficient. A small slit-like valvular opening is occasionally found, at the upper margin of the fossa, leading upward beneath the limbus into the left atrium, the remains of the fetal aperture between the two atria.</p>\n<p><strong>Highyeild:</strong></p><p>The atrioventricular (AV) node is a small structure in the heart located in the Koch triangle, near the coronary sinus on the interatrial septum. In a right-dominant heart, the right coronary artery supplies the atrioventricular node.</p>\n<p><strong>Random:</strong></p><p>Boundaries of the Triangle of Koch are: Option A: Septal cusp of the tricuspid valve Option B: Tendon of Todaro Option D: Coronary sinus Edges of the triangle of Koch</p>\n<p><strong>Extraedge:</strong></p><p>The SA node, also known as the sinus node, represents a crescent-like shaped cluster of myocytes divided by connective tissue, spreading over a few square millimeters. It is located at the junction of the crista terminals in the upper wall of the right atrium and the opening of the superior vena cava. These cells can spontaneously generate an electrical impulse.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "All of the following pairs about the boundaries of the ischiorectal fossa are correct except:", "options": [{"label": "A", "text": "Anterior: Perineal Membrane", "correct": false}, {"label": "B", "text": "Posterior: Gluteus maximus", "correct": false}, {"label": "C", "text": "Medial: Levator ani", "correct": false}, {"label": "D", "text": "Lateral: Obturator externus", "correct": true}], "correct_answer": "D. Lateral: Obturator externus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral: Obturator externus The following structure forms the lateral boundary of the Ischiorectal fossa Tuberosity of the ischium Obturator internus muscle Obturator fascia</p>\n<p><strong>Highyeild:</strong></p><p>The ischioanal fossa (formerly called ischiorectal fossa ) is the fat-filled wedge-shaped space lateral to the anal canal and inferior to the pelvic diaphragm. It is somewhat prismatic in shape, with its base directed to the surface of the perineum and its apex at the line of the meeting of the obturator and anal fasciae.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Anterior: Perineal Membrane The perineal membrane forms the anterior boundary of the Ischiorectal fossa. Option B. Posterior: Gluteus maximus The Gluteus maximus and Sacrotuberous ligament form the anterior boundary of the Ischiorectal fossa. Option C. Medial: Levator ani Levator ani and sphincter ani externus muscle form a medial boundary of the ischiorectal fossa.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following nerves is injured during incision and drainage of an ischiorectal abscess?", "options": [{"label": "A", "text": "Superior Rectal Nerve", "correct": false}, {"label": "B", "text": "Inferior rectal nerve", "correct": true}, {"label": "C", "text": "Superior gluteal nerve", "correct": false}, {"label": "D", "text": "Inferior gluteal nerve", "correct": false}], "correct_answer": "B. Inferior rectal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior rectal nerve Inferior rectal nerves and vessels are content of Ischiorectal Fossa.</p>\n<p><strong>Highyeild:</strong></p><p>Contents of Ischioanal Fossa Ischioanal pad of fat. Inferior rectal nerves and vessels. They pass through the fossa from the lateral to the medial side. They arch upwards above the fat to supply mucous membrane, external sphincter and the skin around the anus. Pudendal canal with its contents. This canal lies along the lateral wall of the fossa. Posterior scrotal or posterior labial (in females) nerves and vessels. They cross the anterolateral part of the fossa and enter the urogenital triangle. Perineal branch of the fourth sacral (S4) nerve. It enters the posterior angle of the fossa and runs over the levator ani to the external anal sphincter. They are perforating cutaneous branches of nerves S2, S3. They appear at the lower border of the gluteus maximus, in the posterior part of the fossa. Content of Ischiorectal Fossa</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options A, B & C are not the content of the Ischiorectal fossa.</p>\n<p><strong>Extraedge:</strong></p><p>Pudendal Canal is a fascial canal in the lateral wall of the ischioanal fossa, enclosing the pudendal nerve and internal pudendal vessels.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the below statements is not true about ischiorectal fossa?", "options": [{"label": "A", "text": "Obturator fascia meets anal fascia at the apex", "correct": false}, {"label": "B", "text": "A communication is present between the two IRF in front of anal canal", "correct": true}, {"label": "C", "text": "Alcock’s canal is located at the lateral wall", "correct": false}, {"label": "D", "text": "Inferior rectal nerves and vessels pass through it.", "correct": false}], "correct_answer": "B. A communication is present between the two IRF in front of anal canal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A communication is present between the two IRF in front of anal canal The horseshoe recess connects the two ischioanal fossa behind the anal canal.</p>\n<p><strong>Highyeild:</strong></p><p>Recesses of Ischiorectal fossa These are narrow extensions of the fossa beyond its boundaries. The anterior recess extends forwards above the perineal membrane, reaching almost up to the posterior surface of the body of the pubis. It is closely related to the prostate or the vagina The posterior recess is smaller than the anterior. It extends deep to the sacrotuberous ligament. The horseshoe recess connects the two ischioanal fossa behind the anal canal. Horse shoe Recesses of Ischiorectal fossa</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Obturator fascia meets anal fascia at the apex The apex is formed by the line where the obturator fascia meets the inferior fascia of the pelvic diaphragm or anal fascia. The sequence corresponds to the origin of the levator ani from the lateral pelvic wall. Option C. Alcock’s canal is located at the lateral wall Pudendal Canal: This is a fascial canal in the lateral wall of the ischioanal fossa, enclosing the pudendal nerve and internal pudendal vessels. The fascia of the canal is fused with the lower part of the obturator fascia laterally, with the lunate fascia above, with the perianal fascia medially, and with the falciform process of the sacrotuberous ligament below. Option D. Inferior rectal nerves and vessels pass through it. Inferior rectal nerves and vessels pass through the fossa from lateral to medial side. They arch upwards above the fat to supply mucous membrane, external sphincter and the skin around the anus.</p>\n<p><strong>Extraedge:</strong></p><p>Ischioanal Space This is large and deep. The fat in this space is loosely arranged in large loculi formed by incomplete delicate septa. Therefore, the infections of this space are the least painful because swelling can occur without tension. The lunate fascia arches over the ischioanal fat. It begins laterally at the pudendal canal and merges medially with the fascia covering the deep part of the external anal sphincter. The fascia divides the ischioanal space into: Suprategmental space, above the fascia. Tegmental space, below the fascia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "37-year-old man presented with acute penile pain, penile swelling, and the inability to pass urine after blunt trauma. In this patient with penile injury, Colles fascia prevents extravasation of urine in:", "options": [{"label": "A", "text": "Ischiorectal Fossa", "correct": true}, {"label": "B", "text": "Abdomen", "correct": false}, {"label": "C", "text": "Perineum", "correct": false}, {"label": "D", "text": "None", "correct": false}], "correct_answer": "A. Ischiorectal Fossa", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ischiorectal Fossa Colle's fascia prevents the passage of extravasated urine due to rupture of urethra backwards into ischiorectal fossa. Colles' fascia is attached posteriorly to the posterior border of the perineal membrane and on each side to the pubic arch below the crus penis. Anteriorly, it is continuous with the fascia of the scrotum containing the dartos, the fascia of the penis, and the membranous layer of the superficial fascia of the anterior abdominal wall or fascia, the Scarpa.</p>\n<p><strong>Highyeild:</strong></p><p>Below the level of the umbilicus, the superficial fascia of the anterior abdominal wall is divided into a superficial fatty layer (fascia of Camper) and a deep membranous layer (fascia of Scarpa). The fatty layer is continuous with the superficial fascia of the adjoining part of the body. In the penis, it is devoid of fat, and in the scrotum, it is replaced by the dartos muscle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B, C & D None are incorrect answers because collect fascia prevents the passage of extravasated urine due to rupture of the urethra backwards into the ischiorectal fossa. The membranous layer is continuous below with a similar membranous layer of the superficial fascia of the perineum known as Colles’ fascia. The attachments of Scarpa’s fascia of the abdomen and Colles’ fascia of the perineum are such that they prevent the passage of extravasated urine due to the rupture of the urethra backwards into the ischiorectal fossa and downwards into the thigh. Colles' fascia is attached posteriorly to the posterior border of the perineal membrane and on each side to the pubic arch below the crus penis. Anteriorly, it is continuous with the fascia of the scrotum containing the dartos, the fascia of the penis, and the membranous layer of the superficial fascia of the anterior abdominal wall or fascia, the Scarpa.</p>\n<p><strong>Extraedge:</strong></p><p>The inferior rectal nerve (S2–4) supplies the skin around the anus and over the ischioanal fossa. The perineal branch of the fourth sacral nerve supplies the skin posterior to the anus .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45 yr old male patient is posted for abscess drainage from the ischioanal fossa. While draining the abscess, the surgeon injured the nerve in Alcock's canal. Which nerve is injured in the scenario?", "options": [{"label": "A", "text": "Obturator Nerve", "correct": false}, {"label": "B", "text": "Genitofemoral nerve", "correct": false}, {"label": "C", "text": "Pudendal nerve", "correct": true}, {"label": "D", "text": "Accessory obturator nerve", "correct": false}], "correct_answer": "C. Pudendal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pudendal nerve PUDENDAL CANAL : This is a fascial tunnel in the lateral wall of the ischioanal fossa, just above the sacrotuberous ligament. It transmits the pudendal nerve and the internal pudendal vessels.</p>\n<p><strong>Highyeild:</strong></p><p>Contents of Pudendal Canal Pudendal nerve (S2, S3, S4): In the posterior part of the canal, the pudendal nerve gives off the inferior rectal nerve and then soon divides into a more significant perineal nerve a smaller dorsal nerve of the penis. Internal pudendal artery : This artery gives off the inferior rectal artery in the posterior part of the canal. In the anterior part of the canal, the artery divides into the perineal artery and the artery of the penis. The vein accompanies the artery. Pudendal canal</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Obturator Nerve, option B. Genitofemoral nerve and option D. Accessory obturator nerves are incorrect answers because the pudendal nerve and the internal pudendal vessels transmit through the pudendal canal.</p>\n<p><strong>Extraedge:</strong></p><p>The pudendal nerve arises from the sacral plexus in the pelvis. It is derived from spinal nerves S2–4.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All the following are the contents of the ischioanal fossa except:", "options": [{"label": "A", "text": "Inferior rectal nerve and vessels", "correct": false}, {"label": "B", "text": "Pudendal nerve and internal pudendal vessels", "correct": false}, {"label": "C", "text": "Middle rectal vessels", "correct": true}, {"label": "D", "text": "Ischioanal pad of fat", "correct": false}], "correct_answer": "C. Middle rectal vessels", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Middle rectal vessels Contents of Ischioanal Fossa Ischioanal pad of fat. Inferior rectal nerves and vessels. They pass through the fossa from the lateral to the medial side. They arch upwards above the fat to supply mucous membrane, external sphincter and the skin around the anus. Pudendal canal with its contents. This canal lies along the lateral wall of the fossa. Posterior scrotal or posterior labial (in females) nerves and vessels. They cross the anterolateral part of the fossa and enter the urogenital triangle. Perineal branch of the fourth sacral (S4) nerve. It enters the posterior angle of the fossa and runs over the levator ani to the external anal sphincter. They are perforating cutaneous branches of nerves S2, S3. They appear at the lower border of the gluteus maximus, in the posterior part of the fossa.</p>\n<p><strong>Highyeild:</strong></p><p>The chief neurovascular bundle of the perineum occupies a fascial tunnel, the pudendal canal, and contains the pudendal nerve and the internal pudendal vessels. The pudendal canal lies in the lateral wall of the ischioanal fossa.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Inferior rectal nerve and vessels Option B. Pudendal nerve and internal pudendal vessels Option D. Ischioanal pad of fat Options A, B and C all are contents of the Ischiorectal fossa.</p>\n<p><strong>Extraedge:</strong></p><p>The occasional gap between the tendinous origin of the levator ani and the obturator fascia is known as the hiatus of Schwalbe. Rarely, pelvic organs may herniate through this gap into the ischioanal fossa, resulting in an ischioanal hernia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "After an accident, a patient is admitted in the emergency department with deep wounds and severe bleeding. The patient complained of pain in the left hypochondriac and left lumbar region . On examination, it was found that the direction of the wound is from the posterior abdominal wall nearer to the median plane at L1 vertebral level. As an intern, what is your diagnosis about the structure damaged and the artery involved in bleeding?", "options": [{"label": "A", "text": "Spleen; splenic artery", "correct": false}, {"label": "B", "text": "Right kidney;right renal artery", "correct": false}, {"label": "C", "text": "Left kidney;left renal artery", "correct": true}, {"label": "D", "text": "Body of stomach; left gastric artery", "correct": false}], "correct_answer": "C. Left kidney;left renal artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left kidney;left renal artery Because kidneys are retroperitoneal organs situated on the posterior abdominal wall. They occupy epigastric, hypochondriac, and umbilical regions. As they extend from T12-L3 vertebral level, and hilum of the left kidney lies at the L1 level nearer to the median plane that consists of the renal artery, whose rupture is responsible for severe bleeding in this case.</p>\n<p><strong>Highyeild:</strong></p><p>The following structures are seen in the hilum from the anterior side to the posterior side. The renal vein The renal artery The renal pelvis, which is the expanded upper end of the ureter. Hilum of kidney relation</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A: Incorrect because the spleen is present in mainly left hypochondriac and partly in the epigastrium. It is not extending into the umbilical region nor present in the posterior abdominal wall. Option B: Incorrect because the question mentioned about the left hypochondriac region not the right one. Option D: Incorrect because the stomach is not extending in the lumbar region and not present near the posterior abdominal wall mentioned in the question.</p>\n<p><strong>Extraedge:</strong></p><p>The right kidney is related to the twelfth rib, and the left kidney to eleventh and twelfth ribs .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 14-year-old boy comes to an emergency department; her father told her that during the football game, he had met with an injury. After that, he complained of severe pain on the posterior abdominal wall of the right side, mainly in the hypochondriac and lumbar regions. On examination, the doctor found tenderness below the 12th rib, and pain increased while pressing this region. What is your diagnosis?", "options": [{"label": "A", "text": "Injury to spleen", "correct": false}, {"label": "B", "text": "Injury to the right kidney", "correct": true}, {"label": "C", "text": "Injury to the left kidney", "correct": false}, {"label": "D", "text": "Injury to the pancreas", "correct": false}], "correct_answer": "B. Injury to the right kidney", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Injury to the right kidney Because the pain is felt in the region of renal angle [angle between 12th rib and outer border of erector spinae muscle ] commonly injured in cases of lower thoracic cage injury and tenderness is felt here on inspiration.</p>\n<p><strong>Highyeild:</strong></p><p>Anterior relations of the kidneys</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. INCORRECT as the spleen is present on the left side of the abdomen. Option: C. incorrect as the question mentioned right-sided pain and injury, so the left kidney is not injured. Option: D. Incorrect as the pancreas is present on the left side of the body. #</p>\n<p><strong>Extraedge:</strong></p><p>The posterior relations of the two kidneys are the same, except that the right kidney is related to one rib while the left kidney is related to two ribs: Four muscles: Diaphragm, quadratus lumborum, psoas major, and transversus abdominis. Three nerves: Subcostal (T12), iliohypogastric (L1), and ilioinguinal (L1). The subcostal nerve is accompanied by the subcostal vessels. One or two ribs: The right kidney is related to the 12th rib, whereas the left kidney is related to the 11th and 12th ribs.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 42-year-old lady was diagnosed with pneumothorax leading to respiratory distress. She had a history of renal surgery one year back, following which she started having this respiratory distress. She has no history of respiratory problems before the surgery or any relevant family history. The 12th rib was not found during the investigation, but the 11th rib was found normal. What may cause her symptoms?", "options": [{"label": "A", "text": "Due to the rupture of their lungs and collection of blood in the pleural cavity, which leads to her symptoms", "correct": false}, {"label": "B", "text": "Due to a fracture of their 11th rib leading to pleural effusion, which leads to her symptoms", "correct": false}, {"label": "C", "text": "The 11th rib was mistaken as the 12th rib during surgery, leading to rupture of the pleural cavity, which led to her symptoms", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. The 11th rib was mistaken as the 12th rib during surgery, leading to rupture of the pleural cavity, which led to her symptoms", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The 11th rib was mistaken as the 12th rib during surgery, leading to rupture of the pleural cavity, which led to her symptoms In surgical exposure of the kidney when the 12th rib is absent or too small, sometimes the 11th rib is mistaken as the 12th one, so the chances of damaging the pleural cavity increase, leading to a pneumothorax-like condition.</p>\n<p><strong>Highyeild:</strong></p><p>CAPSULES (COVERINGS) OF KIDNEY From within outwards, the kidney is surrounded by four capsules/coverings as follows: Fibrous capsule (true capsule). Perirenal (perinephric) fat. Renal fascia (false capsule). Pararenal (perinephric) fat.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect as pneumothorax means leakage of air in the pleural cavity, not blood. Option: B. Incorrect as pneumothorax means air leakage in the pleural cavity, not pleural effusion. Option D. , None of the above, is an incorrect answer because, In surgical exposure of the kidney when the 12th rib is absent or too small, sometimes the 11th rib is mistaken as the 12th one, so the chances of damaging the pleural cavity increases leading to a pneumothorax-like condition.</p>\n<p><strong>Extraedge:</strong></p><p>RENAL FASCIA (FALSE CAPSULE/ FASCIA OF GEROTA) It is a fibrolamellar sheath that surrounds the kidney and perirenal fat. It consists of the following two layers. Ill-defined anterior layer (fascia of Toldt). A well-defined posterior layer (fascia of Zuckerkandl).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 42-year-old male complained of severe pain in the lower abdominal region; the pain starts in the loin region and radiates down the groin. Recently on examination in the nephrology department, he was diagnosed with ureteric stones. Which is the most likely site of the stone to get impacted in the ureters in this patient?", "options": [{"label": "A", "text": "Point of the crossing of the ureter by the broad ligament of the uterus", "correct": false}, {"label": "B", "text": "While passing on the tip of the transverse process of vertebra", "correct": false}, {"label": "C", "text": "At the site of enlargement of the uterine artery", "correct": false}, {"label": "D", "text": "Point of the crossing of the ureter by ductus deferens", "correct": true}], "correct_answer": "D. Point of the crossing of the ureter by ductus deferens", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Point of the crossing of the ureter by ductus deferens The point of intersection of the ureter by ductus deferens is the site involved because the ureteric stones are liable to become impacted at one of the regular constriction sites of the ureter. These constriction sites have less diameter than other areas of ureters so that stones can be easily lodged here.</p>\n<p><strong>Highyeild:</strong></p><p>Regular constriction sites of ureters are : at the Pelviureteric junction at the brim of the lesser pelvis point of crossing of the ureter by ductus deferens or broad ligament of the uterus during oblique passage through the bladder wall at its opening in the lateral angle of the trigone</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect as the case is of a male patient, and the broad ligament is found in females Option: B. Incorrect because ureters pass medially on the tip of the transverse process, so it was not in direct contact with the vertebra so that no compression can occur through it in typical cases. Option: C. Incorrect uterine arteries are absent in males.</p>\n<p><strong>Extraedge:</strong></p><p>The ureter is supplied by sympathetic from T10 to L1 segments and parasympathetic from S2 to S4 nerves. They reach the ureter through the renal, aortic, and hypogastric plexuses. All the nerves appear to be sensory in function.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 42 year old male patient complained of severe pain in the Loin , radiating along the scrotum and inner side of the thigh. After a radiological examination, it was found that he had ureteric stones. Scrotum was normal, having no inflammation. The possible reason for the radiating pain in this case is.", "options": [{"label": "A", "text": "Due to joint cutaneous innervation by the T11-L2 segment", "correct": true}, {"label": "B", "text": "Due to the inflammation present in the scrotum", "correct": false}, {"label": "C", "text": "Due to standard nerve supply by renal, aortic, and hypogastric plexus to these areas", "correct": false}, {"label": "D", "text": "All of the above", "correct": false}], "correct_answer": "A. Due to joint cutaneous innervation by the T11-L2 segment", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Due to joint cutaneous innervation by the T11-L2 segment In cases of ureteric stones, severe pain in cases of ureteric rocks occurs in the loin area. It radiates towards the groin, scrotum, labia majora, and the inner side of the thigh. Due to standard cutaneous supply to these areas along with ureter by T11-L2 segment.</p>\n<p><strong>Highyeild:</strong></p><p>Ureteric colic: This term is used for severe pain due to a ureteric stone or calculus, which causes spasms of the ureter. The pain starts in the loin and radiates down the groin, the scrotum, the labium majus, and the inner side of the thigh. Note that the pain is referred to the cutaneous areas innervated by segments, mainly T11 to L2, which also supply the ureter. Ureteric colic</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect as the scrotum on examination was found to be expected with no inflammation Option: C. Incorrect as renal, aortic, and hypogastric plexuses do not supply the scrotum and inner side of the thigh. Option: D. Incorrect, as all the given statements need to be corrected.</p>\n<p><strong>Extraedge:</strong></p><p>Ureter is composed of the following: The innermost mucous membrane. The middle layer of the well-developed smooth muscle layer. Outer tunica adventitia. The epithelial lining is of transitional epithelium. The muscle coat in the upper two-thirds has inner longitudinal and outer circular fibers. The lower one-third comprises an additional outer longitudinal layer. Connective tissue forms the outer layer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A girl with Turner’s syndrome is brought to the physician with complaints of nausea and pain in the left side of the abdomen. The following is the MRI scan of the patient’s abdomen. What is the probable diagnosis?", "options": [{"label": "A", "text": "Splenomegaly", "correct": false}, {"label": "B", "text": "Pancreatitis", "correct": false}, {"label": "C", "text": "Horseshoe kidney", "correct": true}, {"label": "D", "text": "Annular pancreas", "correct": false}], "correct_answer": "C. Horseshoe kidney", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1692271701056-QTDA005006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Horseshoe kidney The patient has a congenital defect in her kidney known as the horseshoe kidney, wherein the lower parts of both kidneys are fused. It is the most common congenital anomaly of kidneys. This has increased in people with chromosomal defects such as Turner’s and Down’s syndrome. The Horseshoe kidney is a congenital anomaly of the formation of kidneys. The symptoms include frequent UTIs, nausea, foul-smelling urine, etc. The patient complains of pain on the left side of the abdomen because of the mild ischemia of the left side of the transverse and descending colon. This is because the ascent of the kidney to its normal position is interrupted by the inferior mesenteric artery (the isthmus of the horseshoe kidney is the blockage), and the artery is compressed. This artery is responsible for the blood supply of the hindgut. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Splenomegaly is the enlargement of the spleen in cases of increased hemolysis and some cancers. The spleen is an intraperitoneal organ behind the stomach (stomach bed) on the left side. The MRI scan doesn’t indicate any anomalies on the left side. Hence, it is the wrong answer. Option: B. Pancreatitis is the inflammation of the pancreas. Pancreatitis may start suddenly and last for days or occur over many years. It has many causes, including gallstones, heavy alcohol use, etc. The symptoms include upper abdominal pain, nausea, and vomiting. Since the pain is elicited on the left side and MRI doesn’t indicate it, the answer is wrong. Option: D. Annular pancreas is a congenital defect of the joining of the ventral and dorsal heads of the pancreas. The symptoms include early satiety and nausea due to duodenal atresia. Since the patient doesn’t complain of these symptoms and there is no radiological evidence of the defect, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Retrocaval ureter- Persistence of the posterior cardinal vein, associated with a high confluence of the right and left common iliac veins or a double inferior vena cava, can result in a retrocaval (or circumaural) ureter that passes behind the inferior vena cava, usually at the level of the low edge of the third (horizontal) part of the duodenum before it emerges anterior to it to pass from medial to lateral. A retrocaval ureter occurs in one in 1500 individuals. Most commonly, it has no clinical sequelae, although it can result in upper ureteric obstruction.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 5-year-old male child is brought to the pediatrician complaining of greasy and bulky stools, intermittent constipation, difficulty breathing, and wheezing. The child’s mother says her parents also suffered the same symptoms. The following Image shows the affected organ. Which of the following is the probable diagnosis?", "options": [{"label": "A", "text": "Cystic Fibrosis", "correct": true}, {"label": "B", "text": "Von Hippel-Lindau disease", "correct": false}, {"label": "C", "text": "Polycystic kidney disease", "correct": false}, {"label": "D", "text": "Lymphangioma", "correct": false}], "correct_answer": "A. Cystic Fibrosis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1692271701147-QTDA005007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cystic Fibrosis The above image is of a pancreas that is affected by cystic fibrosis. It is a hereditary disease that affects the lungs and the digestive system. Here, the body produces thick and sticky mucus that clogs the lungs, obstructs the pancreas, and prevents them from secreting essential chemicals and hormones. Cystic fibrosis affecting the pancreas will prevent the secretion of pancreatic lipase and amylase. This will result in the malabsorption of fats and carbohydrates; hence the stool is foul smelly, less dense, and dull- It is hereditary and also causes breathing problems. Hence it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Cystic fibrosis is inherited in an autosomal recessive manner. It is caused by mutations in both copies of the gene for the cystic fibrosis transmembrane conductance regulator (CFTR) protein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Von Hippel-Lindau disease/ syndrome (VHL) is a hereditary condition wherein tumors arise within multiple organs. The VHL-related tumors include hemangioblastomas. These are blood vessel tumors of the brain, spinal cord, and retina. Hence, it is the wrong answer. Option: C. Polycystic kidney is a congenital renal disease wherein there are urine-filled pouches of the walls of the kidney. There is a problem while urinating but no problems in the stool. Hence, it is the wrong answer. Option: D. Lymphangioma is the swelling or mass commonly occurring in the head, neck, and mouth. They are the result of some congenital conditions. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>At least 97% of men with cystic fibrosis are infertile but not sterile and can have children with assisted reproductive techniques. The leading cause of infertility in men with cystic fibrosis is the congenital absence of the vas deferens (which usually connects the testes to the ejaculatory ducts of the penis), but potentially also by other mechanisms such as causing no sperm, abnormally shaped sperm, and few sperm with poor motility. Many men found to have congenital absence of the vas deferens during evaluation for infertility have a mild, previously undiagnosed form of CF. Around 20% of women with CF have fertility difficulties due to thickened cervical mucus or malnutrition. In severe cases, malnutrition disrupts ovulation and causes a lack of menstruation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A sixty-year-old man consults a physician complaining of sharp intermittent pain of the side of the lower abdomen. He also complains of hematuria, nausea, sweating, vomiting, and malaise. Blood tests indicate an elevated urea and calcium level. The following Image shows the patient’s intravenous pyelogram (IVP). What is the probable diagnosis?", "options": [{"label": "A", "text": "Nephrolithiasis", "correct": true}, {"label": "B", "text": "Pyelonephritis", "correct": false}, {"label": "C", "text": "Renal tumors", "correct": false}, {"label": "D", "text": "Renal infarction", "correct": false}], "correct_answer": "A. Nephrolithiasis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1692271701211-QTDA005008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Nephrolithiasis Nephrolithiasis is also known as renal calculi, and it is a disease that also affects the urinary tract. Kidney stones are small deposits made of calcium, phosphate, and other components of foods that build up in the kidneys. They usually result in hematuria. Nephrolithiasis is also known as renal calculi, and it is a disease that also affects the urinary tract. They usually result in hematuria. They are typically diagnosed by ultrasound, intravenous pyelography (IVP), or a CT scan, along with blood tests that indicate an increased calcium and urea content. Hence, it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Renal pain: The renal pain is felt in the loin and often radiates downward and forward into the groin. The nature of pain varies from dull aches to severe spasmodic pain. The renal pain occurs either due to stretching of the renal capsule or due to spasms of the smooth muscle in the renal pelvis. The afferent fibers pass successively through the renal plexus, lowest splanchnic nerve, and sympathetic trunk and enter the T12 spinal segment. The pain is commonly referred to along the subcostal nerve to the flank and anterior abdominal wall and the ilioinguinal nerve (L1) into the groin.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Pyelonephritis is the inflammation of the kidney that is usually due to a bacterial infection. The symptoms include fever, tenderness, nausea, burning sensation while urinating, and frequent urination. It doesn’t increase blood calcium content. Hence, it is the wrong answer. Option: C. Renal tumors are abnormal growths in the kidney. These masses may be benign or malignant. They mainly don’t elevate the blood urea level. They also don’t elicit sharp pain. Hence, it is the wrong answer. Option: D. Renal infarction results from an interruption in the regular blood supply to part of or to the entire kidney. The two major causes of renal infarction are thromboembolism and in situ thrombosis. They don’t increase the blood urea and calcium level, but they increase LDH levels. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Referred pain - Excessive distension of the ureter or spasm of its muscle can be caused by a stone (calculus) and provokes severe pain (ureteric colic, which is commonly, but mistakenly, called renal colic). The pain is spasmodic and agonizing, particularly if the obstruction is gradually forced down the ureter by the muscle spasm. It is referred to cutaneous areas innervated from spinal segments that supply the ureter, mainly T11–L2, and shoots superomedially down to the scrotum or labium majus; it can extend into the proximal anterior aspect of the thigh by projection to the genitofemoral nerve (L1, L2). The cremaster with the same innervation may retract the testis reflexly.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A woman in her forties is admitted to the ER as having fainted. She has a history of dizziness, anxiety, palpitations, and weight loss. The heart rate is elevated, and the VMA level is increased in the urine. The patient doesn’t present with any structural and functional deformities. The following Image is an MRI scan at the T12-L1 level. What is the diagnosis?", "options": [{"label": "A", "text": "Familial Dysautonomia", "correct": false}, {"label": "B", "text": "Pheochromocytoma", "correct": true}, {"label": "C", "text": "Adrenal cysts", "correct": false}, {"label": "D", "text": "Adrenal cortical carcinoma", "correct": false}], "correct_answer": "B. Pheochromocytoma", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1692271701355-QTDA005009IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pheochromocytoma The patient suffers from a rare adrenal medulla tumor known as a It causes increased catecholamine synthesis and abnormal division of the chromaffin cells. Pheochromocytoma is a rare tumor of adrenal medullary tissue wherein the chromaffin cells are enlarged. Hence, it is called chromaffin oma. It results in the excessive release of epinephrine and norepinephrine. The symptoms include flushing of the skin, high blood pressure, sweating, dizziness, fatigue, palpitations, headache, anxiety, nausea, shortness of breath, tremors, and weight loss. The catecholamines are broken down rapidly and are excreted in the urine as Vanillyl Mandelic Acid (VMA) at an increased level than usual. Hence, it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Pheochromocytoma-related hypertensive emergencies are one of the most feared clinical manifestations. Attacks are random and may occur secondary to a trigger or spontaneously after a catecholamine surge. The predominant symptom is elevated systolic blood pressure (> 200 mmHg) unresponsive to traditional treatment regimens and threatens end-organ damage. Patients require immediate, life-saving treatment to prevent further damage to other organs and death.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Familial dysautonomia is a genetic disorder that affects the development, differentiation, and survival of certain nerve cells. This disorder disturbs cells in the ANS. Hence, involuntary activities like digestion, breathing, lacrimation, and regulating blood pressure and body temperature are altered to a varied extent. Since the patient doesn’t present with any structural and functional deformities, the answer is wrong. Option: C. Adrenal cysts are rare cystic masses that arise from the adrenal medullary interstitium. They are generally non-functional, and asymptomatic when smaller than 10 cm in diameter. There is no marked increase in the VMA levels in the urine. Hence, it is the wrong answer. Option: D. Adrenal cortical carcinoma is a rare disease wherein neoplastic cells are formed in the outer layer of the adrenal gland known as the adrenal cortex. This condition usually presents with a lump on the back and is generally associated with diabetes. There is no significant rise in the VMA levels in the urine. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>The signs and symptoms of pheochromocytoma are those related to sympathetic nervous system hyperactivity. The classic triad includes headaches (likely related to elevated blood pressure or hypertension), tachycardia/elevated heart rate, and diaphoresis (excessive sweating, particularly at night, also known as hyperhidrosis).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Fusion of the caudal portions of kidneys during embryonic development is most likely to result in which of the following congenital conditions?", "options": [{"label": "A", "text": "Bicornuate Uterus", "correct": false}, {"label": "B", "text": "Cryptorchidism", "correct": false}, {"label": "C", "text": "Horseshoe kidney", "correct": true}, {"label": "D", "text": "Hypospadias", "correct": false}], "correct_answer": "C. Horseshoe kidney", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Horseshoe kidney During development, the kidneys typically “ascend” from a position in the pelvis to a position high on the posterior abdominal wall. Although the kidneys are bilateral structures, occasionally, the inferior poles of the two kidneys fuse. When this happens, the “ascent” of the fused kidneys is arrested by the first midline structure they encounter, the inferior mesenteric artery. The incidence of horseshoe kidneys is about 0.25% of the population.</p>\n<p><strong>Highyeild:</strong></p><p>Ureter to uterine artery: “Water under the bridge.” The uterine artery crosses the ureters (which carry water). A common surgical error could be to ligate and cut the ureter with the uterine artery while removing the uterus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Bicornuate Uterus A bicornuate uterus is a uterine malformation produced due to impairment in the fusion of Mullerian ducts. The bicornuate uterus is a rare anomaly but associated with worse reproductive outcomes; recurrent pregnancy loss and preterm labor are most common. Option B. Cryptorchidism Cryptorchidism , also known as undescended testis , is the failure of one or both testes to descend into the scrotum. Option D. Hypospadias Hypospadias is a common variation in the fetal development of the penis in which the urethra does not open from its usual location in the head of the penis.</p>\n<p><strong>Extraedge:</strong></p><p>Non-union of the excretory and collecting parts of the kidney results in the formation of a congenital polycystic kidney.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A young man in his twenties consults a physician as he feels a mass in his abdomen while standing. He also complains of frequent hematuria. The symptoms are relieved on lying down. General examination shows an abnormal renal angle examination. What is the diagnosis?", "options": [{"label": "A", "text": "Polycystic Kidney", "correct": false}, {"label": "B", "text": "Nephritis", "correct": false}, {"label": "C", "text": "Horseshoe kidney", "correct": false}, {"label": "D", "text": "Nephroptosis", "correct": true}], "correct_answer": "D. Nephroptosis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Nephroptosis The clinical vignette comes to a diagnosis of nephroptosis . It is a congenital condition in which there is no support for the kidney, hence, it freely floats in the abdominal cavity and is seen as a mass on standing; the renal angle is the angle between the 12th rib and the psoas major muscle for palpating the kidney, it is abnormal here due to the free-floating nature. The symptoms include hematuria, proteinuria, nausea, a feeling of weight in the abdomen, flanking pain on the affected side, vomiting, hypertension, etc.</p>\n<p><strong>Highyeild:</strong></p><p>Blood from a ruptured kidney or pus in a perinephric abscess first distends the renal fascia, then forces its way within the renal fascia downwards into the pelvis. It cannot cross to the opposite side because of the fascial septum and midline attachment of the renal fascia.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Polycystic kidney is a congenital anomaly; here, there are several urine-filled out pouches on the kidney surface. It causes hypertension, but it gives a regular renal angle examination. Hence, it is the wrong answer Option: B. Nephritis is also known as glomerulonephritis, and it is the inflammation of the nephrons in the kidney. It causes cloudy, pus-filled urine and doesn’t show abnormal renal angle examination. Hence, it is the wrong answer Option: C. Horseshoe kidney is another congenital anomaly wherein the kidneys of both sides are joined together inferiorly. It usually doesn’t cause any serious problems. In some cases, it can cause ischemia of the part of the colon supplied by the inferior mesenteric artery. It doesn’t happen. The symptoms aren’t relieved when lying down. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Kidney is palpated bimanually, with one hand placed in front and the other behind the flank. When enlarged, the lower pole of the kidney becomes palpable on deep inspiration.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 21 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 62-year-old male patient expresses concern that his voice has changed over the preceding months. Imaging is done and it reveals a growth located within the aortic arch, adjacent to the left pulmonary artery. Which neural structure is most likely being compressed to cause the changes in the patient’s voice?", "options": [{"label": "A", "text": "Left Phrenic Nerve", "correct": false}, {"label": "B", "text": "Esophageal plexus", "correct": false}, {"label": "C", "text": "Left recurrent laryngeal nerve", "correct": true}, {"label": "D", "text": "Left vagus nerve", "correct": false}], "correct_answer": "C. Left recurrent laryngeal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left recurrent laryngeal nerve The left recurrent laryngeal nerve passes beneath the ligamentum arteriosum and then loops superiorly toward the tracheoesophageal groove, medial to the arch of the aorta.</p>\n<p><strong>Highyeild:</strong></p><p>The recurrent laryngeal nerve (RLN) is a branch of the vagus nerve (cranial nerve X) that supplies all the intrinsic muscles of the larynx, with the exception of the cricothyroid muscles. There are two recurrent laryngeal nerves, right and left. The right and left nerves are not symmetrical, with the left nerve looping under the aortic arch, and the right nerve looping under the right subclavian artery then travelling upwards. They both travel alongside the trachea.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Left Phrenic Nerve On the left, the phrenic nerve crosses anterior to the first part of the subclavian artery . Option B. Esophageal plexus Lying in the fibrous wall of the esophagus, the plexus receives filaments from the sympathetic trunks and greater splanchnic nerves; the preganglionic fibres arise mainly from the lower segments of the thoracic spinal cord. Option D. Left vagus nerve The left vagus crosses in front of the left subclavian artery to enter the thorax between the left common carotid and subclavian arteries. It descends on the left side of the aortic arch, which separates it from the left pleura, and travels behind the phrenic nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The recurrent laryngeal nerves supply sensation to the larynx below the vocal cords, give cardiac branches to the deep cardiac plexus, and branch to the trachea, esophagus and inferior constrictor muscles. The posterior cricoarytenoid muscles, the only muscles that can open the vocal folds, are innervated by this nerve. The recurrent laryngeal nerves are the nerves of the sixth pharyngeal arch.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 32-year-old woman in her 3rd trimester of pregnancy is undergoing a routine USG. The examination of the fetus reveals enlarged and echogenic lungs, an inverted diaphragm, and fatal ascites. Which condition is best characterized by these signs?", "options": [{"label": "A", "text": "Laryngeal Atresia", "correct": true}, {"label": "B", "text": "Tracheal atresia", "correct": false}, {"label": "C", "text": "Polyhydramnios", "correct": false}, {"label": "D", "text": "Lung hypoplasia", "correct": false}], "correct_answer": "A. Laryngeal Atresia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Laryngeal Atresia Laryngeal atresia (congenital high airway obstruction syndrome) is a rare obstruction of the upper fetal airway. Distal to the site of the atresia, the airways dilate, lungs enlarge and become echogenic, the diaphragm flattens or inverts, and fetal ascites and/or hydrops develop.</p>\n<p><strong>Highyeild:</strong></p><p>Laryngeal atresia is generally a fatal congenital anomaly with an incidence of 1: 50,000 births. This congenital anomaly is a condition of multifactorial inheritance, in which the fetus has a dilated trachea, enlarged echogenic lungs, an inverted or flattened diaphragm, fetal hydrops, and ascites.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Tracheal atresia Tracheal atresia is a rare obstruction of the trachea, commonly found with a tracheoesophageal fistula, probably resulting from the unequal division of the foregut into esophagus and trachea. Option C. Polyhydramnios Polyhydramnios is an excess of amniotic fluid, often associated with esophageal atresia or tracheoesophageal fistula. Option D. Lung hypoplasia Lung hypoplasia is reduced lung volume, often seen in infants with a congenital diaphragmatic hernia. Oligohydramnios, or a decrease in amniotic fluid, is associated with stunted lung development and pulmonary hypoplasia.</p>\n<p><strong>Extraedge:</strong></p><p>Diagnosis of Laryngeal atresia is usually made when there is a failure to perform endotracheal intubation in a neonate with severe respiratory distress and absence of audible cry.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 2-year-old child is seen in the pediatric cardiology unit for a congenital heart condition. Which conditions occur most often?", "options": [{"label": "A", "text": "Membranous ventricular septal defect", "correct": true}, {"label": "B", "text": "Tetralogy of Fallot", "correct": false}, {"label": "C", "text": "Muscular ventricular septal defect", "correct": false}, {"label": "D", "text": "Ostium secundum defect", "correct": false}], "correct_answer": "A. Membranous ventricular septal defect", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Membranous ventricular septal defect Ventricular septal defects account for 25% of congenital heart defects. The most common of these are defects in the membranous portion of the interventricular septum (membranous ventricular septal defects).</p>\n<p><strong>Highyeild:</strong></p><p>Ventricular septal defects (VSDs) are the most common congenital cardiac anomaly in children and the second most common congenital abnormality in adults , second only to bicuspid aortic valves. Membranous ventricular septal defects are more common than muscular ventricular septal defects and are the most common congenital cardiac anomaly.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Tetralogy of Fallot The prevalence of tetralogy of Fallot is estimated to be 1 in 3,000 live births. Children with chromosome disorders, such as Down syndrome, often have tetralogy of Fallot and other congenital heart diseases. Option C. Muscular ventricular septal defect Trabecular (muscular) ventricular septal defect (VSD) is the second most common type of VSD, occurring in 15-20% of most series. Option D. Ostium secundum defect Isolated secundum atrial septal defects account for approximately 7% of congenital cardiac defects. Congenital heart defects of significance occur in approximately 8 per 1000 live births. Therefore, 5-6 cases of secundum atrial septal defect occur per 10,000 live births.</p>\n<p><strong>Extraedge:</strong></p><p>Congenital VSDs are frequently associated with other congenital conditions, such as Down syndrome</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 2-day-old is diagnosed with transposition of the great arteries. If this condition were to be left untreated for more than 4 months, it would be fatal. Which of the following structures must remain patent so that the infant can survive until surgical correction of the malformation?", "options": [{"label": "A", "text": "Ductus Arteriosus", "correct": true}, {"label": "B", "text": "Umbilical arteries", "correct": false}, {"label": "C", "text": "Umbilical vein", "correct": false}, {"label": "D", "text": "Coarctation of the aorta", "correct": false}], "correct_answer": "A. Ductus Arteriosus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ductus Arteriosus In the case of transposition of the great arteries, oxygenated blood travels from the left ventricle into the pulmonary trunk, where it will eventually reach the lungs. In contrast, the aorta would be carrying deoxygenated blood into the systemic circulation. A patent ductus arteriosus acts as a shunt between the aorta and pulmonary trunk, allowing oxygenated and deoxygenated blood to mix and therefore allowing some oxygenated blood to reach the tissues.</p>\n<p><strong>Highyeild:</strong></p><p>Transposition of the great vessels occurs when the conotruncal septum fails to follow its normal spiral course and runs straight As a consequence, the aorta originates from the right ventricle, and the pulmonary artery originates from the left ventricle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:B. Umbilical arteries Option:C. Umbilical vein Option:D. Coarctation of the aorta None of the other answer choices would correct this problem; with these structures remaining patent, the body would still not receive sufficient oxygenated blood for survival to be possible.</p>\n<p><strong>Extraedge:</strong></p><p>TGV condition, which occurs in 4.8/10,000 births, sometimes is associated with a defect in the membranous part of the interventricular It is usually accompanied by an open ductus arteriosus. Because the SHF and neural crest cells contribute to the formation and septation of the outflow tract, respectively, insults to these cells contribute to cardiac defects involving the outflow tract.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 2-day-old newborn female is diagnosed with pulmonary stenosis, overriding of the aorta, ventricular septal defect, and hypertrophy of the right ventricle. Condition is best characterized by these signs?", "options": [{"label": "A", "text": "Tetralogy of Fallot", "correct": true}, {"label": "B", "text": "Atrial septal defect", "correct": false}, {"label": "C", "text": "Transposition of the great vessels", "correct": false}, {"label": "D", "text": "Pulmonary atresia", "correct": false}], "correct_answer": "A. Tetralogy of Fallot", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tetralogy of Fallot Tetralogy of Fallot is always characterized by four cardiac defects: pulmonary stenosis, ventricular septal defect (VSD), and overriding aorta, and these, in turn, lead to right ventricular hypertrophy.</p>\n<p><strong>Highyeild:</strong></p><p>Tetralogy of Fallot, the most frequently occurring abnormality of the conotruncal region, is due to an unequal division of the conus resulting from the anterior displacement of the conotruncal septum. Displacement of the septum produces four cardiovascular alterations: a narrow right ventricular out-flow region, pulmonary infundibular stenosis; a large defect of the interventricular septum; an overriding aorta that arises directly above the septal defect; and hypertrophy of the right ventricular wall because of higher pressure on the right side.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:B. Atrial septal defect An atrial septal defect (ASD) is characterized by the communication between the two atria. Option:C. Transposition of the great vessels In the case of transposition of the great vessels, the aorta arises from the right ventricle and the pulmonary trunk arises from the left ventricle. Option:D. Pulmonary atresia Pulmonary atresia is a birth defect of the heart where the valve that controls blood flow from the heart to the lungs doesn't form at all. In babies with this defect, blood has trouble flowing to the lungs to pick up oxygen for the body.</p>\n<p><strong>Extraedge:</strong></p><p>Tetralogy of Fallot occurs in 9.6/10,000 births but occurs as a common feature in individuals with Alagille syndrome. In addition to the heart defect, these people have abnormalities in other organs, including the liver, and a characteristic face with a broad prominent forehead, deep-set eyes, and a small pointed In 90% of cases, there is a mutation in JAG1, the ligand for NOTCH signalling that regulates neural crest cells forming the conotruncal [outflow tract] septum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 2-day-old newborn female is diagnosed with pulmonary stenosis, overriding of the aorta, ventricular septal defect, and hypertrophy of the right ventricle. Which of the following embryologic mechanisms is most likely responsible for the development of this cluster of anomalies?", "options": [{"label": "A", "text": "Superior malalignment of the subpulmonary infundibulum", "correct": true}, {"label": "B", "text": "Defect in the aorticopulmonary septum", "correct": false}, {"label": "C", "text": "Endocardial cushion defect", "correct": false}, {"label": "D", "text": "Total anomalous pulmonary venous connections", "correct": false}], "correct_answer": "A. Superior malalignment of the subpulmonary infundibulum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior malalignment of the subpulmonary infundibulum Superior malalignment of the subpulmonary infundibulum causes stenosis of the pulmonary trunk. This leads to the four symptoms mentioned and is known as tetralogy of Fallot.</p>\n<p><strong>Highyeild:</strong></p><p>Tetralogy of Fallot (TOF), is a congenital heart defect characterized by four specific cardiac defects. Classically, the four defects are: pulmonary stenosis, which is the narrowing of the exit from the right ventricle; a ventricular septal defect, which is a hole allowing blood to flow between the two ventricles; right ventricular hypertrophy, which is a thickening of the right ventricular muscle; and an overriding aorta, which is where the aorta expands to allow blood from both ventricles to enter.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:B. Defect in the aorticopulmonary septum A defect in the formation of the aorticopulmonary septum is characteristic of the transposition of the great arteries. Option:C. Endocardial cushion defect An endocardial cushion defect is associated with membranous ventricular septal defects. Option:D. Total anomalous pulmonary venous connections Total anomalous pulmonary venous return (TAPVR) is a birth defect of the heart. In a baby with TAPVR, oxygen-rich blood does not return from the lungs to the left atrium. Instead, the oxygen-rich blood returns to the right side of the heart. Here, oxygen-rich blood mixes with oxygen-poor blood.</p>\n<p><strong>Extraedge:</strong></p><p>In addition, the tetralogy of Fallot may present with other anatomical anomalies, including: stenosis of the left pulmonary artery, in 40% a bicuspid pulmonary valve, in 60% right-sided aortic arch, in 25% coronary artery anomalies, in 10% a patent foramen ovale or atrial septal defect, in which case the syndrome is sometimes called a pentalogy of Fallot an atrioventricular septal defect partially or anomalous pulmonary venous return.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 5-year-old boy is admitted to the hospital with severe dyspnea. During physical examination a loud systolic murmur and a wide, fixed, split S2 sound is noted. What is the most likely diagnosis?", "options": [{"label": "A", "text": "Ventricular Septal Defect", "correct": false}, {"label": "B", "text": "Atrial septal defect", "correct": true}, {"label": "C", "text": "Tetralogy of Fallot", "correct": false}, {"label": "D", "text": "Transposition of the great arteries", "correct": false}], "correct_answer": "B. Atrial septal defect", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Atrial septal defect Most patients with ASD are asymptomatic but as cardiac failure develops they may present with shortness of breath, palpitations, and weakness. Chest auscultation classically reveals an ejection systolic murmur heard at the left upper sternal border, attributed to increased flow across the pulmonary valve rather than blood shunting across the defect itself.</p>\n<p><strong>Highyeild:</strong></p><p>The ostium secundum atrial septal defect is the most common type of atrial septal defect and comprises 6–10% of all congenital heart diseases. It involves a patent ostium secundum (that is, a patent foramen secundum). The secundum atrial septal defect usually arises from an enlarged foramen ovale, inadequate growth of the septum secundum, or excessive absorption of the septum primum. About 10 to 20% of individuals with ostium secundum ASDs also have mitral valve prolapse . An ostium secundum ASD accompanied by acquired mitral valve stenosis is called Lutembacher's syndrome.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Ventricular Septal Defect A murmur resulting from a VSD will be pansystolic and prominent at the lower left sternal border. Option:C. Tetralogy of Fallot Tetralogy of Fallot does not cause a murmur at S1 or S2.tetralogy of Fallot, including bluish-looking skin or a heart murmur (a “whooshing” sound caused by blood not flowing properly through the heart). However, it is not uncommon for a heart murmur to be absent right at birth. Option:D . Transposition of the great arteries Murmurs: murmurs are not typically present unless a small VSD or pulmonic stenosis exists. A murmur resulting from a VSD will be pansystolic and prominent at the lower left sternal border. Pulmonic stenosis causes a systolic ejection murmur at the upper left sternal border</p>\n<p><strong>Extraedge:</strong></p><p>Complications of an uncorrected secundum ASD include pulmonary hypertension and right-sided congestive heart failure.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 3-month-old infant is diagnosed with Down's syndrome. A routine CVS examination reveals that the infant suffers from arrhythmias. What other cardiac conditions are most likely to occur with Down syndrome?", "options": [{"label": "A", "text": "Tetralogy of Fallot", "correct": false}, {"label": "B", "text": "Transposition of the great arteries", "correct": false}, {"label": "C", "text": "Atrial septal and ventricular septal defects", "correct": true}, {"label": "D", "text": "Truncus arteriosus", "correct": false}], "correct_answer": "C. Atrial septal and ventricular septal defects", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Atrial septal and ventricular septal defects Down syndrome (more properly called “trisomy 21”) is associated with cardiovascular abnormalities such as arrhythmias and atrial and ventricular septal defects. It is also characterized by mental retardation, brachycephaly, flat nasal bridge, the upward slant of the palpebral fissure, protruding tongue, simian crease, and clinodactyly of the fifth digit.</p>\n<p><strong>Highyeild:</strong></p><p>An atrioventricular septal defect (AVSD) occurs when there are holes between the right and left sides of the heart, and the valves that control the blood flow between the two sides may not be formed correctly. AVSD is the most common congenital heart condition in children with Down syndrome. In AVSD, blood is allowed to flow where it normally should not go. Blood can go from the lungs, where it gets oxygen, to the heart, then back to the lungs without taking the oxygen to the rest of the body. The extra blood flow to the lungs causes high pressure and forces the heart to work harder.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Tetralogy of Fallot, Option B. Transposition of the great arteries and Option D. Truncus arteriosus are incorrect answers because AVSD is the most common congenital heart condition in children with Down syndrome.</p>\n<p><strong>Extraedge:</strong></p><p>Tetralogy of Fallot is considered a critical congenital heart condition because the child could need surgery soon after birth. Tetralogy of Fallot reduces the amount of oxygen in the body causing potentially serious problems. These include heart infections, irregular heartbeats, dizziness, fainting, seizures, and delayed growth.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 3-month-old infant on a check-up is diagnosed with a deletion at the 22q11 chromosome. A routine cardiovascular examination reveals severe congenital cardiac malformation. Which of the following malformations will most likely be associated with 22q11 syndrome?", "options": [{"label": "A", "text": "Tetralogy of Fallot and truncus arteriosus", "correct": true}, {"label": "B", "text": "Transposition of the great arteries", "correct": false}, {"label": "C", "text": "Atrial septal and ventricular septal defects", "correct": false}, {"label": "D", "text": "Coarctation of the aorta", "correct": false}], "correct_answer": "A. Tetralogy of Fallot and truncus arteriosus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tetralogy of Fallot and truncus arteriosus Tetralogy of Fallot and truncus arteriosus are associated with Digeorge syndrome (22q11).</p>\n<p><strong>Highyeild:</strong></p><p>2 Deletion syndrome is the most common deletion syndrome in humans and has several presentations, including DiGeorge syndrome . The defects are the result of a deletion on the long arm of chromosome 22 and occur in ap- proximately1 per 4,000 births. Recent evidence shows that mutations in one of the genes in the deletion interval, TBX1 [T-box DNA binding transcription factor 1], result in the same syndrome without a deletion.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:B . Transposition of the great arteries Transposition of the great arteries is associated with maternal diabetes Option:C . Atrial septal and ventricular septal defects ASDs and VSDs are present in individuals with Down syndrome. Option:D . Coarctation of the aorta Coarctation of the aorta is related to Turner syndrome.</p>\n<p><strong>Extraedge:</strong></p><p>Marfan syndrome is present in individuals with aortic atresia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In the diagram given below, different muscles of the larynx are marked by labelled arrows. Abduction of the vocal cord is done:", "options": [{"label": "A", "text": "A", "correct": true}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "A. A", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681401608-QTDA027010IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A A- Posterior cricoarytenoid – abductor of the vocal cord.</p>\n<p><strong>Highyeild:</strong></p><p>The posterior cricoarytenoid muscles are paired muscles that take origin from the central ridge on the back of the cricoid cartilage to insert into the muscular process of the arytenoid cartilage. They are the main abductors of the vocal folds. ' Muscles of Larynx</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:B- Cricothyroid – tensor of the vocal cord. Option:C - Lateral cricoarytenoid – adductor of the vocal cord. Option:D- Transverse arytenoid – adductor of the vocal cord.</p>\n<p><strong>Extraedge:</strong></p><p>The cricothyroid muscle, which rotates the major laryngeal cartilages , in turn passively stretches and tightens the vocal folds. As they lengthen and become stiffer, the fundamental frequency of vocal fold vibration increases and a higher-pitched sound is produced.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is a true statement regarding marked structures in the given laryngeal wall?", "options": [{"label": "A", "text": "A- is accompanied by Vocalis muscle deep to its mucosa", "correct": false}, {"label": "B", "text": "B- Helps in the closure of rima glottidis", "correct": true}, {"label": "C", "text": "C- thickening of the lower border of conus elasticus", "correct": false}, {"label": "D", "text": "D- is an elastic type of cartilage", "correct": false}], "correct_answer": "B. B- Helps in the closure of rima glottidis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681401633-QTDA027011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>B- Helps in the closure of rima glottidis B is sag. section through interarytenoid muscle and is responsible for the closure of rima glottidis (both intercartilaginous and intramembranous parts).</p>\n<p><strong>Highyeild:</strong></p><p>The cavity of the larynx extends from the inlet of the larynx to the lower border of the cricoid cartilage. The inlet of the larynx is placed obliquely. It looks backwards and upwards and opens into the laryngopharynx. The inlet is bounded anteriorly, by the epiglottis; posteriorly, by the interarytenoid fold of mucous membrane; and on each side, by the aryepiglottic fold. Cavity of Larynx</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. is vestibular fold (Vocalis muscle is deep to vocal fold instead) Option:C. is the vocal ligament and it is formed by the thickening of the upper border of cricovocal membrane (aka conus elasticus) Option:D. is a section through the arch of the cricoid cartilage (thyroid, cricoid and base of arytenoid are hyaline cartilages and the rest are elastic).</p>\n<p><strong>Extraedge:</strong></p><p>Within the cavity of the larynx, there are two folds of mucous membrane on each side. The upper fold is the vestibular fold, and the lower fold is the vocal fold. The space between the right and left vestibular folds is the rima vestibuli, and the space between the vocal folds is the rima glottidis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The level of the Adult larynx is:", "options": [{"label": "A", "text": "C3 To C6", "correct": true}, {"label": "B", "text": "C7 to T1", "correct": false}, {"label": "C", "text": "C3 to C4", "correct": false}, {"label": "D", "text": "C2 to C7", "correct": false}], "correct_answer": "A. C3 To C6", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C3 To C6 Location and Extent Of Larynx The larynx lies in the anterior midline of the neck, extending from the root of the tongue to the trachea. In the adult male, it lies in front of the third to sixth cervical vertebrae, but in children and adult females, it lies at a little higher level (at C1 to C4 level).</p>\n<p><strong>Highyeild:</strong></p><p>In adult humans, the larynx is found in the anterior neck at the level of the cervical vertebrae C3–C6 . It connects the inferior part of the pharynx (hypopharynx) with the trachea. The laryngeal skeleton consists of nine cartilages: three single (epiglottic, thyroid and cricoid) and three paired (arytenoid, corniculate, and cuneiform). The hyoid bone is not part of the larynx, though the larynx is suspended from the hyoid. The larynx extends vertically from the tip of the epiglottis to the inferior border of the cricoid cartilage. Its interior can be divided into supraglottis, glottis and subglottis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:B . C7 to T1 Option:C . C3 to C4 Option:D . C2 to C7 All above are incorrect answers because, The larynx lies in the anterior midline of the neck, extending from the root of the tongue to the trachea. In the adult male, it lies in front of the third to sixth cervical vertebrae, but in children and the adult female, it lies at a little higher level (at C1 to C4 level).</p>\n<p><strong>Extraedge:</strong></p><p>The intrinsic laryngeal muscles are responsible for controlling sound production. Cricothyroid muscles lengthen and tense the vocal cords. Posterior cricoarytenoid muscles abduct and externally rotate the arytenoid cartilages, resulting in abducted vocal cords. Lateral cricoarytenoid muscles adduct and internally rotate the arytenoid cartilages, increasing medial compression. Transverse arytenoid muscle adducts the arytenoid cartilages, resulting in adducted vocal cords. Oblique arytenoid muscles narrow the laryngeal inlet by constricting the distance between the arytenoid cartilages. Thyroarytenoid muscles narrow the laryngeal inlet, shortening the vocal cords, and lowering voice pitch. The internal thyroarytenoid is the portion of the thyroarytenoid that vibrates to produce sound.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The laryngeal skeleton has cartilages:", "options": [{"label": "A", "text": "3 paired, 2 unpaired", "correct": false}, {"label": "B", "text": "3 paired, 3 unpaired", "correct": true}, {"label": "C", "text": "2 paired, 3 unpaired", "correct": false}, {"label": "D", "text": "2 paired, 2 unpaired", "correct": false}], "correct_answer": "B. 3 paired, 3 unpaired", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>3 paired, 3 unpaired There are nine cartilages, three unpaired and three paired (3 pairs=6), that support the mammalian larynx and form its skeleton.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A . 3 paired, 2 unpaired Option:C . 2 paired, 3 unpaired Option:D . 2 paired, 2 unpaired Above all options are incorrect because, there are nine cartilages, three unpaired and three paired (3 pairs=6), that support the mammalian larynx and form its skeleton.</p>\n<p><strong>Extraedge:</strong></p><p>Basal parts of arytenoids are composed of hyaline cartilage and tend to ossify after 25 years of age and can be seen in radiographs. Whereas, apices of arytenoids are made up of elastic cartilage and do not ossify.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statements regarding the marked structures is CORRECT?", "options": [{"label": "A", "text": "A is a branch of the Thyrocervical trunk", "correct": false}, {"label": "B", "text": "B is supplied by Ansa Cervicalis", "correct": false}, {"label": "C", "text": "C drains into the internal jugular vein", "correct": true}, {"label": "D", "text": "D innervates the mucosa of the larynx above the vocal cords", "correct": false}], "correct_answer": "C. C drains into the internal jugular vein", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681401731-QTDA027014IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C drains into the internal jugular vein C in the given image is the middle thyroid vein which drains into IJV. Thyroid gland and nerves related</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. A is a branch of the Thyrocervical trunk A is a superior laryngeal artery and it is, a branch of the superior thyroid artery. Option:B . B is supplied by Ansa Cervicalis B is Thyrohoid, The thyrohyoid muscle is supplied by the hypoglossal nerve (XII). It is the only infrahyoid muscle that is not supplied by the ansa cervicalis. It is also supplied by the thyrohyoid branch of cervical spinal nerve 1 (C1). This is via the cervical plexus. D innervates the mucosa of the larynx above the vocal cords D is a recurrent laryngeal nerve, supplying innervation to all of the intrinsic muscles of the larynx, except for the cricothyroid muscles, as well as sensation to the larynx below the level of the vocal cords.</p>\n<p><strong>Extraedge:</strong></p><p>The recurrent laryngeal nerves are the nerves of the sixth pharyngeal arch. The existence of the recurrent laryngeal nerve was first documented by the physician Galen.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Extrinsic membranes of the larynx are all, except:", "options": [{"label": "A", "text": "Conus Elasticus", "correct": true}, {"label": "B", "text": "Thyrohyoid", "correct": false}, {"label": "C", "text": "Hyoepiglottic", "correct": false}, {"label": "D", "text": "Cricotracheal", "correct": false}], "correct_answer": "A. Conus Elasticus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Conus Elasticus Conus elasticus is an intrinsic membrane, while ther options mentioned are extrinsic membranes.</p>\n<p><strong>Highyeild:</strong></p><p>Extrinsic membranes and ligaments of the larynx Thyrohyoid membrane Median thyrohyoid ligament Median thyrohyoid ligament Hyo-epiglottic ligament Cricotracheal ligament Extrinsic membranes and ligaments of the larynx</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Thyrohyoid Hyoepiglottic Cricotracheal All Options mentioned above are incorrect because they are extrinsic membranes of the</p>\n<p><strong>Extraedge:</strong></p><p>The intrinsic ligaments are responsible for holding the cartilages of the larynx together as one functional unit internall Quadrate membrane Conus elasticus or cricovocal membrane Vestibular fold and Vocal fold</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Singer, who has maintained a demanding work schedule, worries about the effect on her vocal cords. The epithelium covering the vocal cords is which of the following?", "options": [{"label": "A", "text": "Pseudostratified Ciliated", "correct": false}, {"label": "B", "text": "Simple columnar", "correct": false}, {"label": "C", "text": "Simple cuboidal", "correct": false}, {"label": "D", "text": "Stratified squamous", "correct": true}], "correct_answer": "D. Stratified squamous", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Stratified squamous A stratified squamous epithelium covers the vocal cords or folds. This epithelium protects the underlying tissue from the mechanical stress acting on the surface of the vocal cords. A simple squamous epithelium is not suitable for protection.</p>\n<p><strong>Highyeild:</strong></p><p>vocal folds are composed of layered structures which are quite different at the histological level . The topmost layer comprises stratified squamous epithelium which is bordered by ciliated pseudostratified epithelium.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. The rest of the larynx is covered with a pseudostratified ciliated epithelium (ie, a respiratory epithelium. Option: B, C. Simple columnar and simple cuboidal epithelia are found more commonly in organs with secretory or absorptive functions.</p>\n<p><strong>Extraedge:</strong></p><p>The inner-lining surface of this squamous epithelium is covered by a layer of mucus (acting as a mucociliary clearance), which is composed of two layers: a mucinous layer and a serous layer. Both mucus layers provide a viscous and watery environment for cilia beating posteriorly and superiorly.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 26 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which of the following is incorrect regarding circumventricular organs?", "options": [{"label": "A", "text": "A -> Pineal gland", "correct": false}, {"label": "B", "text": "B -> Organum vasculosum lamina terminalis", "correct": true}, {"label": "C", "text": "C -> Subfornical organ", "correct": false}, {"label": "D", "text": "D -> Neurohypophysis", "correct": false}], "correct_answer": "B. B -> Organum vasculosum lamina terminalis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392332171-QTDA064001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>B -> Organum vasculosum lamina terminalis Option B, here B marked area is sub commissural organ as shown in the sagittal section of the brain, so option b is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Third Ventricle The third ventricle is the cavity of the It is a midline slit-like cavity situated between the two thalami and the part of the hypothalamus. It extends from the lamina terminalis anteriorly to the superior end of the cerebral aqueduct of the midbrain posteriorly. The cavity of the third ventricle is lined by ciliated columnar epithelium, the ependyma, and traversed by a mass of grey matter, the inter-thalamic adhesion, connecting the two thalami. The outline of the cavity is very irregular due to the presence of several diverticula or recesses.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. A -> Pineal gland Option:C. C -> Subfornical organ Option:D. D -> Neurohypophysis Options A, C and D are correctly labelled as shown in the image above.</p>\n<p><strong>Extraedge:</strong></p><p>Divisions and subdivisions of the diencephalon Divisions Subdivisions Pars dorsalis Thalamus (dorsal thalamus) Metathalamus Epithalamus Medial and lateral geniculate bodies Pineal gland (body), habenular nuclei and commissure, and posterior commissure Pars ventralis Subthalamus (ventral thalamus) Hypothalamus Subthalamic nucleus, and zona inserta</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are seen in the floor of the 3rd ventricle except:", "options": [{"label": "A", "text": "Infundibulum", "correct": false}, {"label": "B", "text": "Oculomotor nerve", "correct": true}, {"label": "C", "text": "Mammillary body", "correct": false}, {"label": "D", "text": "Optic chiasma", "correct": false}], "correct_answer": "B. Oculomotor nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Oculomotor nerve Floor of 3rd ventricle is formed by: Optic chiasma, Infundibulum, Mammillary body, Posterior perforated substance, Tegmentum of mid brain.</p>\n<p><strong>Highyeild:</strong></p><p>The floor of the third ventricle is formed from before backwards by, optic chiasma, tuber cinereum infundibulum (pituitary stalk), mammillary bodies, posterior perforated substance, and tegmentum of the midbrain. Third ventricle boundaries</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Infundibulum Option: C. Mammillary body Option: D. Optic chiasma Options A, C and D are all forming the floor of the third ventricle.</p>\n<p><strong>Extraedge:</strong></p><p>The cavity of the third ventricle extends into the surrounding structures as a pocket-like protrusion called recesses. These are as follows: Infundibular recess . It is a deep tunnel-shaped recess extending downward through the tuber cinereum into the infundibulum, i.e. the stalk of the pituitary gland. Optic (or chiasmatic) recess . It is an angular recess situated at the junction of the anterior wall and the floor of the ventricle just above the optic chiasma. Anterior recess (vulva of the ventricle) . It is a triangular recess which extends anteriorly in front of the interventricular foramen and behind the anterior commissure between the diverging anterior columns of the fornix. Suprapineal recess . It is a fairly capacious blind diverticulum which extends posteriorly above the stalk of the pineal gland and below the tela choroidea. Pineal recess . It is a small diverticulum, which extends posteriorly between the superior and inferior laminae of the stalk of the pineal gland.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The anterior horn of lateral ventricles is related anteriorly to:", "options": [{"label": "A", "text": "Thalamus", "correct": false}, {"label": "B", "text": "Septum pellucidum", "correct": false}, {"label": "C", "text": "Stria terminalis", "correct": false}, {"label": "D", "text": "Corpus callosum", "correct": true}], "correct_answer": "D. Corpus callosum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Corpus callosum Anterior horn of lateral ventricles relation The roof is formed by the undersurface of the anterior part of the body of the corpus callosum. The narrow floor is formed by the upper surface of the rostrum of the corpus callosum. The anterior wall is formed by the genu of the corpus callosum. The medial wall is formed by the septum pellucidum. The lateral wall is formed by the bulging head of the caudate nucleus.</p>\n<p><strong>Highyeild:</strong></p><p>The choroid plexus of the lateral ventricle is derived from the anterior choroidal artery, a branch of the internal carotid artery and the posterior choroidal artery, a branch of the posterior cerebral artery.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option:A. Thalamus Option:C. Stria terminalis Thalamus and stria terminalis form the floor of the body of the lateral ventricle. Option:B. Septum pellucidum The medial wall of the anterior horn of the lateral ventricle is formed by the septum pellucidum.</p>\n<p><strong>Extraedge:</strong></p><p>The outline of ventricles and cerebral gyri can be visualized by air encephalography (also called pneumoencephalography) in which the air or oxygen is introduced into the subarachnoid space through lumbar puncture. The air readily replaces the CSF within the ventricles and subarachnoid space. The air or gas being less dense than the fluid or neural tissue, the ventricles and cerebral gyri are easily visualized.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Correct statements about F marked structure are all except:", "options": [{"label": "A", "text": "It is the largest horn of the lateral ventricle", "correct": false}, {"label": "B", "text": "Present in the parietal lobe", "correct": true}, {"label": "C", "text": "Roof is formed by the tapetum of the corpus callosum", "correct": false}, {"label": "D", "text": "Floor is formed by collateral eminence", "correct": false}], "correct_answer": "B. Present in the parietal lobe", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392332708-QTDA064004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Present in the parietal lobe The marked structure is the inferior horn of the lateral ventricle, which is present in the temporal lobe, and not in the parietal lobe. Lateral ventricle</p>\n<p><strong>Highyeild:</strong></p><p>Parts of the lateral ventricle The central part of the body lies mostly within the parietal lobe and extends from the interventricular foramen in front to the splenium of the corpus callosum behind. The anterior horn is the anterior extension from the central part into the frontal lobe and lies in front of the interventricular foramen and behind the posterior surface of the genu of the corpus callosum. The posterior horn is the backward extension from the central part into the occipital lobe towards the occipital pole. The inferior horn is considered the direct continuation of the main ventricular cavity into the temporal lobe. The inferior horn is the largest of the three horns. It begins where the central part and posterior horn meet and curve around the pulvinar of the thalamus into the temporal lobe to end about 2.5 cm behind the temporal pole. Ventricular system of the brain; lateral view.</p>\n<p><strong>Extraedge:</strong></p><p>The choroid plexus of the lateral ventricle is derived from the anterior choroidal artery, a branch of the internal carotid artery and the posterior choroidal artery, a branch of the posterior cerebral artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Correct statements about C marked structure are all except:", "options": [{"label": "A", "text": "It extends from the splenium to the frontal lobe", "correct": true}, {"label": "B", "text": "It extends from the splenium to the occipital lobe", "correct": false}, {"label": "C", "text": "Roof is formed by the tapetum of the corpus callosum", "correct": false}, {"label": "D", "text": "Medial wall is formed by forceps major", "correct": false}], "correct_answer": "A. It extends from the splenium to the frontal lobe", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392332774-QTDA064005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>It extends from the splenium to the frontal lobe The marked structure is the posterior horn of the lateral ventricle. It extends from the splenium of the corpus callosum to the occipital lobe. Lateral ventricle</p>\n<p><strong>Highyeild:</strong></p><p>There are two lateral ventricles , one in each cerebral hemisphere. Each lateral ventricle is a roughly C-shaped cavity situated within each cerebral hemisphere. The lateral ventricle wraps itself around the thalamus, the lentiform nucleus, and the caudate nucleus. It is lined with ependyma and filled with cerebrospinal fluid. It has a capacity of about 7–10 ml. The main parts of the two ventricles are separated from each other by a septum extending between the corpus callosum and fornix called the septum pellucidum.</p>\n<p><strong>Extraedge:</strong></p><p>Each lateral ventricle communicates with the third ventricle through the interventricular foramen (of Monro). Most of the CSF in the CNS is produced by the choroid plexuses of two lateral ventricles.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were studying the drainage system of the brain. Which of the following statements in the given option is correct regarding the given structure?", "options": [{"label": "A", "text": "The anterior horn lies within the parietal lobe.", "correct": false}, {"label": "B", "text": "The anterior horns of two ventricles are separated by septum pellucidum.", "correct": true}, {"label": "C", "text": "Body of the lateral ventricle lies within the parietal and temporal lobe.", "correct": false}, {"label": "D", "text": "The posterior horn is located in the temporal lobe.", "correct": false}], "correct_answer": "B. The anterior horns of two ventricles are separated by septum pellucidum.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392332909-QTDA064007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The anterior horns of two ventricles are separated by septum pellucidum. In the given question, the marked structure represents the lateral ventricle. The lateral ventricle consists of the anterior horn and body, posterior horn and inferior horn. The anterior horn and the body are separated by septum pellucidum. Hence, the correct answer to this question will be option B.</p>\n<p><strong>Highyeild:</strong></p><p>Cerebrospinal Fluid Physical Characteristics and Composition Appearance Clear and colorless Volume c. 150 mL Rate of production 0.5 mL/min Pressure (spinal tap with patient in lateral recumbent position) 60-150 mm of water Composition Protein 15-45 mg/100 mL Glucose 50-85 mg/100 mL Chloride 720-750 mg/100 mL Number of cells 0-3 lymphocytes/mm³</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - The anterior horn lies within the frontal lobe. (option A is wrong). The body of the lateral ventricle lies within the frontal and parietal lobe(option C is wrong) and extends from the interventricular foramen to the splenium of the corpus callosum. The posterior horn is located in the occipital lobe. (option D is wrong).</p>\n<p><strong>Extraedge:</strong></p><p>Cerebrospinal Fluid Functions Cushions and protects the central nervous system from trauma Provides mechanical buoyancy and support for the brain Serves as a reservoir and assists in the regulation of the contents of the skull Nourishes the central nervous system Removes metabolites from the central nervous system Serves as a pathway for pineal secretions to reach the pituitary gland</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 34-year-old male came to the emergency with complaints of headache for a long time, nausea and dizziness. He also tells you about the difficulty in walking compared to previously when he was normal. On examination, the head appeared enlarged and the circumference of the head was more with respect to normal limits. On radiological imaging, obstruction at the level of structure marked in red was seen. Identify the structure in red and Which of the following ventricular systems will be enlarged in this person?", "options": [{"label": "A", "text": "Foramen of monro; Lateral ventricle", "correct": false}, {"label": "B", "text": "Cerebral aqueduct; Third ventricle and fourth ventricle.", "correct": false}, {"label": "C", "text": "Foramen of monro; Lateral ventricle, third ventricle and fourth ventricle.", "correct": false}, {"label": "D", "text": "Cerebral aqueduct; Lateral ventricle and third ventricle.", "correct": true}], "correct_answer": "D. Cerebral aqueduct; Lateral ventricle and third ventricle.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/questionImage-1690541635580-QTDA064008.png"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cerebral aqueduct; Lateral ventricle and third ventricle. In the given clinical scenario, the patient presents with symptoms of hydrocephalus like dizziness, nausea and chronic headache, gait disturbances. The structure marked in the given image is a cerebral aqueduct and obstruction at that level will lead to dilatation of both lateral and third ventricles. If the obstruction is at the level of the foramen of Monro, then only the lateral ventricle would have dilated. Hence, the answer to this question will be option D.</p>\n<p><strong>Highyeild:</strong></p><p>Circulation and absorption of CSF</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options A and C cannot be the answer as the marked structure is not a foramen of Monro. Option: B is incorrect as cerebral aqueduct obstruction will not lead to dilatation of the third ventricle.</p>\n<p><strong>Extraedge:</strong></p><p>Special Properties of CSF Bile is not found in CSF, even in severe jaundice. • Most of the drugs cannot reach CSF. Antibodies are not found in the CSF hence infections of the CNS are often fatal. Due to the presence of a blood-CSF barrier: There is no CSF-brain barrier , hence if drugs are injected into the subarachnoid space (intrathecal injections) they soon enter the extracellular spaces around the neurons and neuroglia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During your anatomy dissection hall classes, you were taught about the relation of the marked structure. Which of the following statements is not true regarding the relation of the given structure?", "options": [{"label": "A", "text": "Medially by septum pellucidum and fornix.", "correct": false}, {"label": "B", "text": "Superiorly by the corpus callosum.", "correct": false}, {"label": "C", "text": "Floor by septum pellucidum, caudate nucleus, thalamus, thalamostriate vein and stria terminalis.", "correct": true}, {"label": "D", "text": "Floor by thalamus, thalamostriate vein and caudate nucleus.", "correct": false}], "correct_answer": "C. Floor by septum pellucidum, caudate nucleus, thalamus, thalamostriate vein and stria terminalis.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/questionImage-1688648340412-QTDA064009IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Floor by septum pellucidum, caudate nucleus, thalamus, thalamostriate vein and stria terminalis. In the given question, the most appropriate option which is incorrect regarding the relation of the lateral ventricle ( marked structure) is option C as septum pellucidum forms the medial relation and is not present on the floor.</p>\n<p><strong>Highyeild:</strong></p><p>Relations of the posterior horn of the lateral ventricle The roof, lateral wall, and floor are formed by a sheet of fibres (tapetum) from the splenium of the corpus callosum . The posteriorly sweeping fibres of the optic radiation remain separated from the cavity of the posterior horn by the tapetum. The medial wall is invaginated by two ridges; the upper of these, the bulb of the posterior horn is formed by the fibres of forceps major and the lower one, the calcar avis is produced by the anterior part of the calcarine sulcus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Other relations of lateral ventricle: Option: A. Medially by septum pellucidum and fornix. Option: B. Superiorly by the corpus callosum. Option: D . Floor by thalamus, thalamostriate vein and caudate nucleus and stria terminalis.</p>\n<p><strong>Extraedge:</strong></p><p>Communications of the third ventricle Anteriorly on each side, the third ventricle communicates with the lateral ventricle through the interventricular foramen (of Monro), and posteriorly with the fourth ventricle through the cerebral aqueduct (of Sylvius). It receives cerebrospinal fluid (CSF) from the lateral ventricles through interventricular foramina and transports it to the fourth ventricle through the cerebral aqueduct.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were posted in radiology where you were shown the following image by your JR under whom you were posted. He told you that the structure marked as number 1,2,3,4 forms the floor of the third ventricle. Which of the following structures in the given option will not represent any of the marked structures?", "options": [{"label": "A", "text": "Optic Chiasma", "correct": false}, {"label": "B", "text": "Pituitary infundibulum", "correct": false}, {"label": "C", "text": "Tuber cinereum", "correct": false}, {"label": "D", "text": "Thalamus", "correct": true}], "correct_answer": "D. Thalamus", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392333771-QTDA064010IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thalamus In the given question, the radiological image shows the third ventricle with the structure marked representing the floor of the third ventricle which is formed by (as marked)- Optic chiasma Pituitary infundibulum Tuber cinereum Mammillary body. Thalamus (option D) forms the lateral wall and not the floor of the third ventricle. So thalamus will not be represented by the marked structure in the given image. Boundaries and recesses of the third ventricle, as seen in the sagittal section,</p>\n<p><strong>Highyeild:</strong></p><p>The cavity of the third ventricle extends into the surrounding structures as a pocket-like protrusion called recesses. These are as follows: Infundibular recess . It is a deep tunnel-shaped recess extending downward through the tuber cinereum into the infundibulum, i.e. the stalk of the pituitary gland. Optic (or chiasmatic) recess . It is an angular recess situated at the junction of the anterior wall and the floor of the ventricle just above the optic chiasma. Anterior recess (vulva of the ventricle) . It is a triangular recess which extends anteriorly in front of the interventricular foramen and behind the anterior commissure between the diverging anterior columns of the fornix. Suprapineal recess . It is a fairly capacious blind diverticulum which extends posteriorly above the stalk of the pineal gland and below the tela choroidea. Pineal recess . It is a small diverticulum, which extends posteriorly between the superior and inferior laminae of the stalk of the pineal gland.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A . Optic Chiasma Option:B. Pituitary infundibulum Tuber cinereum Optic chiasma, pituitary infundibulum and tuber cinereum form the floor of the third ventricle.</p>\n<p><strong>Extraedge:</strong></p><p>The third ventricle is a median cleft between the two thalami. Developmentally, it represents the cavity of the diencephalon, except for the area in front of the interventricular foramen which is derived from the median part of the telencephalon. The cavity is lined by ependyma.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "There is an elevation which is produced by the sulcus on the horns of the lateral ventricle. One such elevation is marked in the given image. Choose the correct statement from the given option with respect to the given image.", "options": [{"label": "A", "text": "The marked elevation is known as calcar avis and is formed by the collateral sulcus.", "correct": false}, {"label": "B", "text": "The marked elevation is known as collateral eminence and is formed by a collateral sulcus.", "correct": false}, {"label": "C", "text": "The marked elevation is known as calcar avis and is formed by calcarine sulcus.", "correct": true}, {"label": "D", "text": "The marked elevation is known as collateral eminence and is formed by the calcarine sulcus.", "correct": false}], "correct_answer": "C. The marked elevation is known as calcar avis and is formed by calcarine sulcus.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392333941-QTDA064011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The marked elevation is known as calcar avis and is formed by calcarine sulcus. The marked structure is known as calcar avis which is formed by calcarine sulcus. It is formed on the posterior horn which is present in the occipital lobe as given in the image. Hence, the correct answer to this question is option C.</p>\n<p><strong>Highyeild:</strong></p><p>The lateral ventricles are the two largest ventricles of the brain and contain cerebrospinal fluid (CSF). Each cerebral hemisphere contains a lateral ventricle, known as the left or right lateral ventricle, respectively. Each lateral ventricle resembles a C-shaped cavity that begins at an inferior horn in the temporal lobe, travels through a body in the parietal lobe and frontal lobe, and ultimately terminates at the interventricular foramina where each lateral ventricle connects to the single, central third ventricle. Along the path, a posterior horn extends backwards into the occipital lobe, and an anterior horn extends farther into the frontal lobe.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. The marked elevation is known as calcar avis and is formed by the collateral sulcus. The marked structure is known as calcar avis which is formed by calcarine sulcus. It is formed on the posterior horn which is present in the occipital lobe as given in the image. Option:B. The marked elevation is backward collateral eminence formed by the collateral sulcus. Collateral eminence is formed on the inferior horn by a collateral sulcus. Option:D. The marked elevation is known as collateral eminence and is formed by the calcarine sulcus. Collateral eminence is formed on the inferior horn by the collateral sulcus.</p>\n<p><strong>Extraedge:</strong></p><p>Tumours in the lower part of the third ventricle give rise to hypothalamic symptoms, like diabetes insipidus, obesity, sexual disturbance, disturbance of sleep, hyperglycemia and glycosuria.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 20 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 34-year-old powerlifter visits the outpatient clinic because he has difficulty walking. During the physical examination, it is observed that the patient has a problem unlocking the knee joint to permit leg flexion. Which of the following muscles is most likely damaged?", "options": [{"label": "A", "text": "Biceps Femoris", "correct": false}, {"label": "B", "text": "Gastrocnemius", "correct": false}, {"label": "C", "text": "Popliteus", "correct": true}, {"label": "D", "text": "Semimembranosus", "correct": false}], "correct_answer": "C. Popliteus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Popliteus Popliteus serves in unlocking the knee; it rotates the distal portion of the femur in a lateral direction. It also draws the lateral meniscus posteriorly, thereby protecting this cartilage as the distal femoral condyle glides and rolls backwards as the knee is flexed. The popliteus is the smallest and most superior of the deep muscles in the posterior compartment of the leg. It unlocks the extended knee at the initiation of flexion and stabilises the knee by resisting lateral (external) rotation of the tibia on the femur.</p>\n<p><strong>Highyeild:</strong></p><p>Explanation for incorrect options:- Option A. Biceps Femoris The biceps femoris is a flexor of the leg and laterally rotates the knee when it is in a position of flexion. Option B. Gastrocnemius The Gastrocnemius is a powerful plantar flexor of the foot. Option D. Semimembranosus The Semimembranosus extends the thigh and flexes the leg at the knee joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The tendon of which of the following muscles is stretched during the patellar reflex?", "options": [{"label": "A", "text": "Quadriceps Femoris", "correct": true}, {"label": "B", "text": "Quadratus femoris", "correct": false}, {"label": "C", "text": "Sartorius", "correct": false}, {"label": "D", "text": "Pectineus", "correct": false}], "correct_answer": "A. Quadriceps Femoris", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Quadriceps Femoris The patella (sesamoid bone) develops within the tendon of the quadriceps femoris muscle when the reflex hammer strikes the patellar ligament resulting in reflex contraction of the quadriceps femoris muscles and extension of the patellar knee reflex. The femoral nerve elicits the reflex arc . The patellar reflex , also called the knee or knee-jerk, is a stretch reflex that tests the spinal cord's L2, L3, and L4 segments .</p>\n<p><strong>Highyeild:</strong></p><p>Patellar Reflex</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Quadratus femoris Quadratus femoris is the muscle of the gluteal region not involved with the patellar reflex. Option C. Sartorius Sartorius: flexor of knee and hip joint Option D. Pectineus Pectineus: flexor of hip joint</p>\n<p><strong>Extraedge:</strong></p><p>For Examining knee and ankle reflexes-a tap with a tendon hammer on the patellar ligament (tendon) tests reflexes at the L3-L4 spinal levels, and tapping the calcaneal tendon tests reflexes at the 5 1 -52 spinal levels.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A healthy young athlete sits at a table with a knee at 90-degree flexion. What will happen when he fully extends the knee?", "options": [{"label": "A", "text": "Movement of tibial tuberosity towards the medial border of the patella", "correct": false}, {"label": "B", "text": "Movement of tibial tuberosity towards the lateral border of the patella", "correct": true}, {"label": "C", "text": "Movement of tibial tuberosity towards the center of the patella", "correct": false}, {"label": "D", "text": "No change in the relationship", "correct": false}], "correct_answer": "B. Movement of tibial tuberosity towards the lateral border of the patella", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Movement of tibial tuberosity towards the lateral border of the patella In sitting posture( when the foot is off the ground), full extension leads to knee locking (by lateral rotation of the tibia). Hence, tibial tuberosity moves laterally towards the lateral border of the patella . The locking mechanism of the knee joint is a crucial function that allows the knee to bear weight and support the body’s weight. It occurs when the knee is fully extended, and the patella (knee cap) locks into place in the femoral groove. The femoral groove is a depression in the femur that the patella fits into, providing stability to the knee joint.</p>\n<p><strong>Highyeild:</strong></p><p>The locking mechanism is controlled by the quadriceps muscle , located in the front of the thigh and is responsible for straightening the knee. When the quadriceps muscle contracts, it helps to stabilise the patella and prevent it from sliding out of place . This ensures the knee is locked in place and ready to bear weight. Locked Knee</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Movement of tibial tuberosity towards the medial border of the patella. Option C. Movement of tibial tuberosity towards the centre of the patella. Option D. No change in the Options A, C and D are incorrect because these movements are not involved during the locking of the knee when the foot is off the ground.</p>\n<p><strong>Extraedge:</strong></p><p>One component of the locking mechanism is a change in the shape and size of the femoral surfaces that articulate with the tibia. In flexion, the surfaces are the curved and rounded areas on the posterior aspects of the femoral condyles. As the knee is extended, the surfaces move to the broad and flat areas on the inferior aspects of the femoral condyles. Consequently, the joint surfaces become more significant and more stable in extension. Another component of the locking mechanism is the medial rotation of the femur on the tibia during extension. Medial rotation and full extension tighten all the associated ligaments. Another feature that keeps the knee extended when standing is that the body's centre of gravity is positioned along a vertical line that passes anterior to the knee joint. The popliteus muscle unlocks the knee by initiating lateral rotation of the femur on the tibia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 13 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 30-year-old female patient comes to OPD with a complaint of increasing muscle weakness and fatigue during the day, requiring her to take frequent rests. She also reports that she cannot enjoy her meals anymore because while chewing her muscles feel fatigued and she has to stop chewing. When she watches television at night sometimes, her vision becomes blurry and she sees double. Her neurologist makes a preliminary diagnosis of myasthenia gravis. Which of the following is the cause of myasthenia gravis?", "options": [{"label": "A", "text": "Acetylcholine synthesis in motor neurons is impaired.", "correct": false}, {"label": "B", "text": "Acetylcholinesterase synthesis is inhibited.", "correct": false}, {"label": "C", "text": "Autoantibodies destroy cholinergic receptors at the postsynaptic membrane preventing the binding of acetylcholine.", "correct": true}, {"label": "D", "text": "Neurotransmitter release is impaired at the presynaptic membrane of the neuromuscular junction.", "correct": false}], "correct_answer": "C. Autoantibodies destroy cholinergic receptors at the postsynaptic membrane preventing the binding of acetylcholine.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Autoantibodies destroy cholinergic receptors at the postsynaptic membrane preventing the binding of acetylcholine. Myasthenia gravis is an autoimmune disorder where autoantibodies target the postsynaptic cholinergic receptors and destroy them. It is a type of Type 2 Hypersensitivity reaction.</p>\n<p><strong>Highyeild:</strong></p><p>Myasthenia gravis (MG) is a long-term neuromuscular junction disease that leads to varying degrees of skeletal muscle weakness. The most commonly affected muscles are the eyes, face, and swallowing. It can result in double vision, drooping eyelids, trouble talking, and trouble walking. Onset can be sudden. Those affected often have a large thymus or develop a thymoma.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Acetylcholine released from motor neurons is thus unable to bind and the muscle contraction weakens due to decreased neurotransmitter communication. Acetylcholine synthesis in motor neurons remains normal. Option: B. Acetylcholinesterase is the enzyme which degrades acetylcholine and its synthesis is not affected in myasthenia gravis. Option: D. The cholinergic neurotransmitter release mechanism at the presynaptic membrane, as well as the signal transduction mechanism within the muscle, remain normal.</p>\n<p><strong>Extraedge:</strong></p><p>Myasthenia gravis is an autoimmune disease of the neuro-muscular junction which results from antibodies that block or destroy nicotinic acetylcholine receptors (AChR) at the junction between the nerve and muscle. This prevents nerve impulses from triggering muscle contractions.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the below-marked cells secrete thyrocalcitonin?", "options": [{"label": "A", "text": "c", "correct": false}, {"label": "B", "text": "a", "correct": false}, {"label": "C", "text": "b", "correct": true}, {"label": "D", "text": "none", "correct": false}], "correct_answer": "C. b", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391598902-QTDA036002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>b Parafollicular cells(C cells) are fewer and lighter cells. Option: C. (b) is parafollicular cells. Parafollicular cells develop from ultimobranchial bodies and they secrete calcitonin which is a tumour marker for medullary thyroid carcinoma. These lie in between the follicles. They secrete thyrocalcitonin which promotes the deposition of Calcium salts in skeletal and other tissues and tends to produce hypocalcemia.</p>\n<p><strong>Highyeild:</strong></p><p>Follicular Cells The follicular cells vary in shape depending on the level of their activity. Normally (at an average level of activity) the cells are cuboidal, and the colloid in the follicles is moderate in amount. When inactive (or resting) the cells are flat (squamous) and the follicles are distended with abundant colloids. Lastly, when the cells are highly active they become columnar and colloid is scanty.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. c Option: B. a Option: D. none Option A (c) is follicular cells and Option B (a) is colloid therefore options A, B and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>C-cells (Parafollicular Cells) They are also called clear cells, or light cells. The cells are polyhedral, with oval eccentric nuclei. Typically, they lie between the follicular cells and their basement membrane. They may, however, lie between adjoining follicular cells; but they do not reach the lumen.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following structures is marked by an arrow?", "options": [{"label": "A", "text": "Endocardium", "correct": false}, {"label": "B", "text": "Tunica media", "correct": false}, {"label": "C", "text": "Tunica externa", "correct": false}, {"label": "D", "text": "Tunica intima", "correct": true}], "correct_answer": "D. Tunica intima", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391599797-QTDA036003IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tunica intima Microscopically, the walls of arteries are made up of Three layers. Out of which tunica intima is the innermost layer Containing an endothelial lining, basal lamina and internal elastic lamina.</p>\n<p><strong>Highyeild:</strong></p><p>Atheroma The most common disease of arteries is atheroma, in which the intima becomes infiltrated with fat and collagen. The thickenings formed are atheromatous plaques. Atheroma leads to the narrowing of the arterial lumen, and consequently to reduced blood flow. Damage to endothelium can induce coagulation of blood forming a thrombus which can completely obstruct the artery. This leads to the death of the tissue supplied. When this happens in an artery supplying the myocardium (coronary thrombosis) it leads to myocardial infarction(manifesting a heart attack) and in the brain (cerebral thrombosis) leads to a stroke and paralysis. An artery weakened by an atheroma may undergo dilation (aneurysm), or may even rupture.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Endocardium The endocardium consists of a single layer of endothelial cells lining the chambers of the heart. Occasionally, small amounts of smooth muscle can also be in the endocardium. Compared to the right atrium, the left atrium has a thicker endocardium because of high pressure from the pulmonary veins Option: B. Tunica media Tunica media is thickest in arteries because of maximum elastic and muscular components. Option: C. Tunica externa Tunica adventitia or tunica externa is the outer layer of the blood vessel wall. It consists of connective tissue with vasa and nervi vasorum and plays a key role in vascular health.</p>\n<p><strong>Extraedge:</strong></p><p>Comparison between an elastic artery and a muscular artery Layers Elastic artery Muscular artery Adventitia It is relatively thin with greater proportion of elastic fibers It consists of thin layer of fibroelastic tissue. Media Made up mainly of elastic tissue in the form of fenestrated concentric membranes. There may be as many as fifty layers of elastic membranes. Made up mainly of smooth muscles arranged circularly Intima It is made up of endothelium, subendothelial connective tissue and internal elastic lamina. The subendothelial connective tissue contains more elastic fibers. The internal elastic lamina is not distinct Intima is well developed, specially internal elastic lamina which stands out prominently.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the epithelium and location from the below-given Image:", "options": [{"label": "A", "text": "Cuboidal Epithelium; Kidney", "correct": false}, {"label": "B", "text": "Transitional epithelium; urinary bladder", "correct": true}, {"label": "C", "text": "Columnar epithelium; pancreas", "correct": false}, {"label": "D", "text": "Cuboidal epithelium; salivary glands", "correct": false}], "correct_answer": "B. Transitional epithelium; urinary bladder", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391600641-QTDA036004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Transitional epithelium; urinary bladder Transitional epithelium is a multi-layered epithelium. The topmost layer contains umbrella-shaped cells in the transitional epithelium. It differs from stratified squamous epithelium in that the cells at the surface are not squamous. The deepest cells are columnar or cuboidal. The middle layers are made up of polyhedral or pear-shaped cells. Cells of the surface layer are large and often shaped like an umbrella.</p>\n<p><strong>Highyeild:</strong></p><p>Mucous Membrane of the urinary bladder The mucous membrane is lined by transitional epithelium. There is no muscularis mucosae. In the empty bladder, the mucous membrane is thrown into numerous folds that disappear when the bladder is distended. Some mucous glands may be present in the mucosa, especially near the internal urethral orifice. When the bladder is distended (with urine) the lining epithelium becomes thinner. This results from the ability of the epithelial cells to change shape and shift over one another.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A . Cuboidal Epithelium; Kidney Option: B. Transitional epithelium; urinary bladder Option: D. Cuboidal epithelium; salivary glands Transitional epithelium is a multi-layered epithelium. The topmost layer contains umbrella-shaped cells in transitional epithelium, as shown in the image, therefore Options A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Ureters are muscular tubes that conduct urine from the renal pelvis to the urinary bladder. The wall of the ureter has three layers: An inner lining of the mucous membrane A middle layer of smooth muscle An outer fibrous coat: adventitia</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A male presented with dyspepsia and abdominal distension. Esophagoscopy was done and a biopsy was taken from the lesion in the esophagus. Which of the following is not true regarding the condition?", "options": [{"label": "A", "text": "Squamous epithelium is replacing Columnar cells", "correct": true}, {"label": "B", "text": "Mucus-secreting cells may be seen", "correct": false}, {"label": "C", "text": "May progress to dysplasia", "correct": false}, {"label": "D", "text": "Risk of malignancy is increased", "correct": false}], "correct_answer": "A. Squamous epithelium is replacing Columnar cells", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391600993-QTDA036005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Squamous epithelium is replacing Columnar cells Barrett's esophagus in which the columnar cells replace the squamous cells. Barrett’s esophagus is a risk factor for adenocarcinoma of the esophagus. Mucin-secreting cells may be seen. The condition can progress to dysplasia and thereafter to malignancy.</p>\n<p><strong>Highyeild:</strong></p><p>Barrett's esophagus is a condition in which there is an abnormal (metaplastic) change in the mucosal cells lining the lower portion of the esophagus, from stratified squamous epithelium to simple columnar epithelium with interspersed goblet cells that are normally present only in the small intestine and large intestine. This change is considered to be a premalignant condition because it is associated with a high incidence of further transition to esophageal adenocarcinoma, often-deadly a cancer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Mucus-secreting cells may be seen Option: C. May progress to dysplasia Option: D. Risk of malignancy is increased The image shown in question is a slide of Barrett's esophagus, in which the columnar cells replace the squamous cells. Mucin-secreting cells may be seen. The condition can progress to dysplasia and thereafter to malignancy, therefore Options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The main cause of Barrett's esophagus is thought to be an adaptation to chronic acid exposure from reflux esophagitis. Barrett's esophagus is diagnosed by endoscopy: observing the characteristic appearance of this condition by direct inspection of the lower esophagus; followed by a microscopic examination of tissue from the affected area obtained from a biopsy.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The cells belonging to the following type of epithelium are provided with an extra reserve of cell membrane:", "options": [{"label": "A", "text": "Transitional", "correct": true}, {"label": "B", "text": "Stratified squamous", "correct": false}, {"label": "C", "text": "Stratified cuboidal", "correct": false}, {"label": "D", "text": "Stratified columnar", "correct": false}], "correct_answer": "A. Transitional", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Transitional Transitional epithelium has the maximum capacity to adjust the shape of apical cells in response to stress. So, the urinary epithelium is the transitional epithelium.</p>\n<p><strong>Highyeild:</strong></p><p>Transitional epithelium Stratified squamous non-keratinizing epithelium Multilayered 4-6 layers Multilayered 4-6 layers Basal cell-cuboidal or columnar Basal cell-cuboidal or columnar Intermediate cell-polyhedral Apical cell - umbrella-shaped cell Intermediate cell-polyhedral Apical cell-squamous-shaped cell Extra reserve of cell membrane No extra reserve of cell membrane They have desmosomes They don't have desmosomes Found in the urinary system Found in the oral cavity, esophagus, vagina, larynx</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Stratified squamous Option: C. Stratified cuboidal Option: D. Stratified columnar Transitional epithelium has a maximum capacity to adjust the shape of apical cells in response to stress, therefore Options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Transitional epithelium is a type of stratified epithelium. Transitional epithelium is a type of tissue that changes shape in response to stretching (stretchable epithelium). The transitional epithelium usually appears cuboidal when relaxed and squamous when stretched. This tissue consists of multiple layers of epithelial cells which can contract and expand in order to adapt to the degree of distension needed. Transitional epithelium lines the organs of the urinary system and is known here as urothelium . The bladder for example has a need for great distension.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The ureter is lined by..........epithelium:", "options": [{"label": "A", "text": "Stratified Squamous", "correct": false}, {"label": "B", "text": "Cuboidal", "correct": false}, {"label": "C", "text": "Ciliated columnar", "correct": false}, {"label": "D", "text": "Transitional", "correct": true}], "correct_answer": "D. Transitional", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Transitional</p>\n<p><strong>Highyeild:</strong></p><p>Transitional Epithelium Found exclusively in renal calyces, renal pelvis, ureters, and bladder. Changes shape in response to distensions caused by fluid accumulation. Transitional epithelium has a maximum capacity to adjust the shape of apical cells in response to stress. So, the urinary epithelium is the transitional epithelium. Plaques in the cells allow extensions of the epithelium during fluid accumulation. During extension or contraction, cell-to-cell contact remains unbroken. Forms a protective osmotic barrier between hypertonic urine and underlying tissue.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Stratified Squamous Option: B. Cuboidal Option: C. Ciliated columnar Ureter is lined by transitional epithelium, so Options A, B and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Transitional epithelium is made up of three types of cell layers: basal, intermediate, and superficial. The basal layer fosters the epithelial stem cells in order to provide constant renewal of the epithelium. These cells' cytoplasm is rich in tonofilaments and mitochondria ; however, they contain a few rough endoplasmic reticulum . The intermediate cell layer is highly proliferative and, therefore, provides for rapid cell regeneration in response to injury or infection of the organ or tube in which it resides. These cells contain a prominent Golgi apparatus and an array of membrane-bound vesicles. These function in the packaging and transport of proteins, such as keratin, to the superficial cell layer. The cells of the superficial cell layer that lines the lumen are known as facet cells or umbrella cells.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which group has a similar kind of epithelium?", "options": [{"label": "A", "text": "Alveoli- Olfactory Epithelium", "correct": false}, {"label": "B", "text": "Olfactory epithelium-skin", "correct": false}, {"label": "C", "text": "Oesophagus - urinary bladder", "correct": false}, {"label": "D", "text": "Lung alveoli - bowman’s capsule", "correct": true}], "correct_answer": "D. Lung alveoli - bowman’s capsule", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lung alveoli - bowman’s capsule Lung alveoli, Bowman’s capsule - simple squamous epithelium. This allows easy exchange of gasses across alveoli.</p>\n<p><strong>Highyeild:</strong></p><p>Squamous epithelium lines the alveoli of the lungs. It lines the free surface of the serous pericardium, the pleura, and the peritoneum; here it is called mesothelium. It lines the inside of the heart, where it is called endocardium; and of blood vessels and lymphatics, where it is called endothelium. Squamous epithelium is also found lining some parts of the renal tubules and in some parts of the internal ear.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Alveoli- Olfactory Epithelium Olfactory epithelium - pseudostratified ciliated columnar epithelium Lung alveoli, Bowman’s capsule - simple squamous epithelium Option: B. Olfactory epithelium-skin Olfactory epithelium - pseudostratified ciliated columnar epithelium Thick skin - keratinized stratified squamous epithelium Thin skin, esophagus - stratified squamous epithelium Option: C. Oesophagus - urinary bladder Urinary bladder - urothelium Esophagus - stratified squamous non-keratinized epithelium</p>\n<p><strong>Extraedge:</strong></p><p>A typical cuboidal epithelium may be seen in the follicles of the thyroid gland, in the ducts of many glands, and on the surface of the ovary. Other sites are the choroid plexuses, the inner surface of the lens, and the pigment cell layer of the retina. A cuboidal epithelium with a prominent brush border is seen in the proximal convoluted tubules of the kidneys.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient underwent cholecystectomy. On histopathological examination, normally the gallbladder epithelium would be?", "options": [{"label": "A", "text": "Simple Squamous", "correct": false}, {"label": "B", "text": "Simple cuboidal", "correct": false}, {"label": "C", "text": "Simple Columnar with brush border", "correct": true}, {"label": "D", "text": "simple Cuboidal with stereocilia", "correct": false}], "correct_answer": "C. Simple Columnar with brush border", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Simple Columnar with brush border Gall bladder lined by tall columnar cells with brush border. The gall bladder doesn’t contain muscularis propria or a proper muscle layer. It contains some smooth muscle fibres and elastic fibres.</p>\n<p><strong>Highyeild:</strong></p><p>Gall bladder histology Gallbladder is a muscular sac situated on the visceral surface of the liver in the fossa for gall bladder. The gallbladder stores and concentrates bile. This bile is discharged into the duodenum when required. The wall of the gallbladder is made up of A mucous membrane A fibromuscular coat A serous layer that covers part of the organ Gall bladder histological slide</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Simple Squamous Option: B . Simple cuboidal Option: D. Simple Cuboidal with stereocilia Gall bladder lined by tall columnar cells with brush border, so Options A, B and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Cells of Gallbladder With the EM the lining cells of the gallbladder are seen to have irregular microvilli on their luminal surfaces. Near the lumen, the lateral margins of the cells are united by prominent junctional complexes. More basally the lateral margins are separated by enlarged intercellular spaces into which complex folds of plasma membrane extend. Numerous blood capillaries are present near the bases of the cells. These features indicate that bile is concentrated by the absorption of water at the luminal surface of the cell. This water is poured out of the cell into basal intercellular spaces from where it passes into blood. Absorption of salt and water from bile into the blood is facilitated by the presence of Na+ and K+ ATPases in cell membranes of cells lining the gallbladder.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Ansa Nephroni is lined by:", "options": [{"label": "A", "text": "Columnar", "correct": false}, {"label": "B", "text": "Low cuboidal and Squamous epithelium", "correct": true}, {"label": "C", "text": "Cuboidal and columnar", "correct": false}, {"label": "D", "text": "Stratified columnar", "correct": false}], "correct_answer": "B. Low cuboidal and Squamous epithelium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Low cuboidal and Squamous epithelium The loop of Henle (Ansa nephroni) is lined by squamous epithelium or Low cuboidal epithelium. Bowman’s capsule is lined by simple squamous epithelium.</p>\n<p><strong>Highyeild:</strong></p><p>Nephron Nephron is the structural and functional unit of the kidney and there are about 1–4 million nephrons in each kidney. The nephron consists of a renal corpuscle (or Malpighian corpuscle), and a long complicated renal tubule. The renal tubule is made up of three parts: The proximal convoluted tubule Loop of Henle The distal convoluted tubule</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Columnar Option: C. Cuboidal and columnar Option: D. Stratified columnar The loop of Henle (Ansa Nephroni) is lined by squamous epithelium or Low cuboidal epithelium, therefore options A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The renal corpuscle is situated in the cortex of the kidney either near the periphery or near the medulla. Based on the situation of the renal corpuscle, the nephrons are classified into two types: Cortical nephrons or superficial nephrons (which have their corpuscles in the outer cortex). Juxtamedullary nephrons (which have their corpuscles in the inner cortex near the medulla or corticomedullary junction).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The lining epithelium of the vagina is", "options": [{"label": "A", "text": "Pseudostratified Columnar Epithelium", "correct": false}, {"label": "B", "text": "Keratinized Stratified Squamous Epithelium", "correct": false}, {"label": "C", "text": "Non-Keratinized Stratified Squamous Epithelium", "correct": true}, {"label": "D", "text": "Ciliated Columnar Epithelium", "correct": false}], "correct_answer": "C. Non-Keratinized Stratified Squamous Epithelium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Non-Keratinized Stratified Squamous Epithelium The vagina is a fibromuscular structure that extends from the cervix to the vestibule of the external genitalia. Its wall has numerous folds and consists of an inner mucosa, a middle muscular layer, and an outer adventitia. The vagina does not have any glands in its wall, and its lumen is lined with a nonkeratinized stratified squamous epithelium.</p>\n<p><strong>Highyeild:</strong></p><p>The mucus produced by cells in the cervical glands lubricates the vaginal lumen. Loose fibroelastic connective tissue and a rich vasculature constitute the lamina propria. Like the cervical epithelium, the vaginal lining is not shed during the menstrual flow. The transformation zone is the area of squamocolumnar transition in the vagina where the columnar epithelium of the endocervix keeps on converting to the squamous epithelium of the ectocervix.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Pseudostratified Columnar Epithelium Option: B. Keratinized Stratified Squamous Epithelium Option: D. Ciliated Columnar Epithelium The vagina does not have any glands in its wall, and its lumen is lined with a nonkeratinized stratified squamous, so Options A, B and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Histology of the Vagina The vagina is composed of four histological layers (internal to external): Stratified squamous epithelium – this layer provides protection and is lubricated by cervical mucus (the vagina itself does not contain any glands). Elastic lamina propria – a dense connective tissue layer which projects papillae into the overlying epithelium. The larger veins are located here. Fibromuscular layer – comprising two layers of smooth muscle; an inner circular and an outer longitudinal layer. Adventitia – a fibrous layer, which provides additional strength to the vagina whilst also binding it to surrounding structures.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Urethra is lined by:", "options": [{"label": "A", "text": "Stratified Columnar Epithelium", "correct": true}, {"label": "B", "text": "Transitional epithelium", "correct": false}, {"label": "C", "text": "Squamous epithelium", "correct": false}, {"label": "D", "text": "Brush border epithelium", "correct": false}], "correct_answer": "A. Stratified Columnar Epithelium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Stratified Columnar Epithelium Only the prostatic urethra is lined by transitional epithelium, the rest of the male urethra and female urethra are lined by stratified columnar.</p>\n<p><strong>Highyeild:</strong></p><p>Mucous Membrane of Urethra The mucous membrane consists of a lining epithelium that rests on connective tissue. The epithelium varies in different parts of the urethra. Both in the male and females, the greater part of the urethra is lined by pseudostratified columnar epithelium. A short part adjoining the urinary bladder is lined by transitional epithelium, while the part near the external orifice is lined by stratified squamous epithelium. The mucosa shows invaginations or recesses into which mucous glands open.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Transitional epithelium Option: C. Squamous epithelium Option: D. Brush border epithelium Only the prostatic urethra is lined by transitional epithelium, the rest of the male urethra and female urethra are lined by stratified columnar, so options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The muscle coat of the urethra consists of an inner longitudinal layer and an outer circular layer of smooth muscle. This coat is better defined in the female urethra. In the male urethra, it is well-defined only in the membranous and prostatic parts, the penile part being surrounded by occasional fibres only. In addition to this smooth muscle, the membranous part of the male urethra and the corresponding part of the female urethra is surrounded by the striated muscle that forms the external urethral sphincter.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Pecten' of the Anal Canal is lined by:", "options": [{"label": "A", "text": "Stratified Columnar Epithelium", "correct": false}, {"label": "B", "text": "Keratinized stratified -squamous epithelium", "correct": false}, {"label": "C", "text": "Simple columnar epithelium", "correct": false}, {"label": "D", "text": "Non-Keratinized stratified squamous epithelium", "correct": true}], "correct_answer": "D. Non-Keratinized stratified squamous epithelium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Non-Keratinized stratified squamous epithelium Upper area (above the pectinate line)- lined by columnar epithelium Pecten area - lined by stratified squamous without keratin- It is a transitional area between the upper area and anal verge or lower area. Anal verge or lower area - lined by keratinized stratified squamous epithelium.</p>\n<p><strong>Highyeild:</strong></p><p>Prominent venous plexuses are present in the submucosa of the anal canal. The internal hemorrhoidal plexus lies above the level of the pectinate line, while the external hemorrhoidal plexus lies near the lower end of the canal.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Stratified Columnar Epithelium Option: B. Keratinized stratified -squamous epithelium Option: C. Simple columnar epithelium Pecten area - lined by stratified squamous without keratin, so options A, B and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Salient features of each region of the stomach Cardia Fundus and body Pylorus Presence of cardiac glands (mucous secreting glands) in lamina propria of mucosa. Cardiac glands are either simple tubular, or compound tubulo alveolar Presence of gastric glands in the lamina propria of mucosa. Gastric glands are simple or branched tubular glands. They secrete enzymes and hydrochloric acid Presence of pyloric glands in the lamina propria of mucosa. Pyloric glands (mucous glands) are simple or branched tubular glands that are coiled. Shallow gastric pits Shallow gastric pits occupying superficial 1/4th or less of the mucosa Shallow gastric pits occupying superficial 1/4th or less of the mucosa Change of epithelium from stratified squamous of the esophagus to simple columnar epithelium in stomach Epithelium is simple columnar. Epithelium is simple columnar. Circular muscle layer is thick and is called as pyloric sphincter.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The marked structure in the given picture contains all of the following except:", "options": [{"label": "A", "text": "Gap Junction", "correct": false}, {"label": "B", "text": "Zone Occludens", "correct": true}, {"label": "C", "text": "Macula Adherens", "correct": false}, {"label": "D", "text": "Desmosomes", "correct": false}], "correct_answer": "B. Zone Occludens", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391601209-QTDA036014IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Zone Occludens Tight junctions , also known as occluding junctions or zonulae occludentes , are multiprotein junctional complexes whose canonical function is to prevent leakage of solutes and water and seals between the epithelial cells. They also play a critical role in maintaining the structure and permeability of endothelial cells. Tight junctions may also serve as leaky pathways by forming selective channels for small cations, anions, or water.</p>\n<p><strong>Highyeild:</strong></p><p>The given slide is a cardiac muscle and the marked structure is an intercalated disc. The intercalated disc is made up of three types of cell junctions: Fascia adherens Gap junctions Desmosomes (Macula adherens)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Gap Junction Option: C. Macula Adherens Option: D. Desmosomes The given slide is a cardiac muscle and the marked structure is an intercalated disc. The intercalated disc is made up of three types of cell junctions: Fascia adherens Gap junctions Desmosomes (Macula adherens) Therefore Options A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Tight junctions prevent the passage of molecules and ions through the space between plasma membranes of adjacent cells, so materials must actually enter the cells (by diffusion or active transport) in order to pass through the tissue.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the organ given on this side:", "options": [{"label": "A", "text": "Gallbladder", "correct": false}, {"label": "B", "text": "Urinary bladder", "correct": true}, {"label": "C", "text": "Skin", "correct": false}, {"label": "D", "text": "Trachea", "correct": false}], "correct_answer": "B. Urinary bladder", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391601280-QTDA036015IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Urinary bladder Given epithelium – transitional epithelium – seen in the urinary bladder. The topmost or apical cells are umbrella-shaped in the transitional epithelium. Urinary bladder histology</p>\n<p><strong>Highyeild:</strong></p><p>From a functional point of view, the kidney may be regarded as a collection of numerous uriniferous tubules that are specialized for the excretion of urine. Each uriniferous tubule consists of an excretory part called the nephron, and of a collecting tubule. The collecting tubules draining different nephrons join to form larger tubules called the papillary ducts (of Bellini), each of which opens into a minor calyx at the apex of a renal papilla. Each kidney contains one to two million nephrons.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Gallbladder Option: C. Skin Option: D. Trachea Given epithelium – transitional epithelium – seen in the urinary bladder. Topmost or apical cells are umbrella-shaped in transitional epithelium, so options A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The renal corpuscle is a rounded structure consisting of (a) a rounded tuft of blood capillaries called the glomerulus; and (b) a cup-like, double-layered covering for the glomerulus called the glomerular capsule (or Bowman’s capsule). The glomerular capsule represents the cup-shaped blind beginning of the renal tubule. Between the two layers of the capsule, there is a urinary space that is continuous with the lumen of the renal tubule.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The cell junction allowing the exchange of cytoplasmic molecules between two cells is called:", "options": [{"label": "A", "text": "Gap Junctions", "correct": true}, {"label": "B", "text": "Tight junctions", "correct": false}, {"label": "C", "text": "Anchoring junctions", "correct": false}, {"label": "D", "text": "Focal junctions", "correct": false}], "correct_answer": "A. Gap Junctions", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Gap Junctions Gap junctions are also spotlike in structure. Gap junctions help in the free flow of ions across membranes. The plasma membranes at gap junctions are closely opposed, and tiny fluid channels called connexons connect the adjacent cells. Molecules, ions, and low-resistance electrical communication occur through these connexons between adjacent cells. These fluid channels are vital in cardiac muscle cells and nerve cells, where fast impulse transmission through the adjacent cells or axons is essential for the synchronization and coordination of normal functions.</p>\n<p><strong>Highyeild:</strong></p><p>Anchoring junctions mechanically attach cells (and their cytoskeletons) to their neighbours or the extracellular matrix.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Tight junctions Tight junctions , also known as occluding junctions or zonulae occludentes , are multiprotein junctional complexes whose canonical function is to prevent leakage of solutes and water and seals between the epithelial cells. They also play a critical role in maintaining the structure and permeability of endothelial cells. Tight junctions may also serve as leaky pathways by forming selective channels for small cations, anions, or water. Option: C. Anchoring junctions Anchoring junctions are cell junctions that are anchored to one another and attached to components of the extracellular matrix. They are important in keeping the cells together and the structural cohesion of tissues. They are commonly found in tissues that are prone to constant mechanical stress, e.g. skin and heart. Option: D. Focal junctions Focal adhesions are large macromolecular assemblies through which mechanical force and regulatory signals are transmitted between the extracellular matrix (ECM) and an interacting cell.</p>\n<p><strong>Extraedge:</strong></p><p>Occluding junctions seal cells together in the epithelium in a way that prevents even small molecules from leaking from one side of the sheet to the other.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Organelles not present in the marked cell:", "options": [{"label": "A", "text": "Mitochondria", "correct": false}, {"label": "B", "text": "Lysozymes", "correct": true}, {"label": "C", "text": "Smooth endoplasmic reticulum", "correct": false}, {"label": "D", "text": "Both a & b", "correct": false}], "correct_answer": "B. Lysozymes", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391601704-QTDA036017IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lysozymes Cardiac myocytes marked in the given slide of cardiac muscle. Cardiac myocytes contain cell organelles like mitochondria & sarcoplasmic reticulum. Lysozymes are enzymes involved in bacterial killing and they are not present in cardiac myocytes.</p>\n<p><strong>Highyeild:</strong></p><p>A cardiomyocyte is a cell responsible for the contraction of the heart – utilizing an intricate network of contractile proteins and ion transporters for this work – with the main purpose of effectively executing the contraction-relaxation cycle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Mitochondria Option: C. Smooth endoplasmic reticulum Option: D. Both a & b Cardiac myocytes marked in the given slide of cardiac muscle. Cardiac myocytes contain cell organelles like mitochondria & sarcoplasmic reticulum. So Options A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Cardiac muscle makes up the thick middle layer of the heart and is surrounded by a thin outer layer called the epicardium or visceral pericardium and an inner endocardium.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Oligodendrocytes are important in:", "options": [{"label": "A", "text": "Blood-Brain Barrier", "correct": false}, {"label": "B", "text": "Myelin formation", "correct": true}, {"label": "C", "text": "Phagocytosis", "correct": false}, {"label": "D", "text": "Chemotaxis", "correct": false}], "correct_answer": "B. Myelin formation", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Myelin formation In CNS, oligodendrocytes are involved in myelin formation – whereas, in PNS, Schwann cells are involved in myelin formation.</p>\n<p><strong>Highyeild:</strong></p><p>Neuroglial cell Function Astrocytes Blood-brain barrier Oligodendrocytes Myelin sheath formation in CNS Schwann cells Microglia Myelin sheath formation in CNS-PNS Phagocyte formation Ependymal Lining the ventricular system of the brain</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Blood-Brain Barrier Option: C. Phagocytosis Option: D. Chemotaxis In CNS, oligodendrocytes are involved in myelin formation, so options A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The blood-brain barrier (BBB) is a highly selective semipermeable border of endothelial cells that prevents solutes in the circulating blood from non-selectively crossing into the extracellular fluid of the central nervous system where neurons reside. The blood- brain barrier is formed by endothelial cells of the capillary wall , astrocyte end-feet ensheathing the capillary, and pericytes embedded in the capillary basement membrane .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Pseudounipolar neurons are seen in:", "options": [{"label": "A", "text": "Olfactory", "correct": false}, {"label": "B", "text": "Celiac ganglion", "correct": false}, {"label": "C", "text": "dorsal root ganglia of spinal nerves", "correct": true}, {"label": "D", "text": "Cochlea", "correct": false}], "correct_answer": "C. dorsal root ganglia of spinal nerves", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>dorsal root ganglia of spinal nerves The dorsal root ganglia contain the pseudo-unipolar cell bodies of the nerve fibres which travel from the ganglia through the root into the spinal cord. The lateral division of the dorsal root contains lightly myelinated and unmyelinated fibres of small diameter. These carry pain and temperature sensation.</p>\n<p><strong>Highyeild:</strong></p><p>Most neurons in the adult organism that exhibit only one process leaving the cell body were initially bipolar during embryonic development. The two neuronal processes fuse during later development and form one axon process. This process then divides close to the cell body into two long axonal branches. One of these branches continues to the CNS, whereas the other branch extends to the peripheral organ. The unipolar neurons (formerly called pseudo-unipolar neurons) are also sensory. The cell bodies of unipolar neurons are found in numerous dorsal root ganglia of spinal nerves and cranial nerve ganglia. The ganglia represent a collection of neurons surrounded by their supportive cells and can be either sensory or motor. Bipolar neurons are also present in the olfactory epithelium, Retina. Types of neurons</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Olfactory Option: B. Celiac ganglion Option: D. Cochlea The dorsal root ganglia contain the pseudo-unipolar cell bodies of the nerve fibres which travel from the ganglia through the root into the spinal cord, so Options A, B and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The axons of dorsal root ganglion neurons are known as afferents. In the peripheral nervous system, afferents refer to the axons that relay sensory information into the central nervous system (i.e. the brain and the spinal cord).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Neuro-epithelial type of sensory receptors is/are found in the following systems except:", "options": [{"label": "A", "text": "Visual", "correct": true}, {"label": "B", "text": "Olfactory", "correct": false}, {"label": "C", "text": "Gustatory", "correct": false}, {"label": "D", "text": "Auditory", "correct": false}], "correct_answer": "A. Visual", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Visual Neuroepithelium is seen in taste buds (gustatory), hair cells (auditory) and also in the olfactory system. Visual sensory receptors are rods and cones which have visual pigment that dissociates on light perception.</p>\n<p><strong>Highyeild:</strong></p><p>The olfactory epithelium includes several distinct cell types. The most important of these is the olfactory receptor neuron, a bipolar cell that gives rise to a small-diameter, unmyelinated axon at its basal surface that transmits olfactory information centrally.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Olfactory Option: C. Gustatory Option: D. Auditory Neuroepithelium is seen in taste buds (gustatory), hair cells (auditory) and also in the olfactory system, so options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Within each sensory epithelium lies sensory cells that act as transducers, converting signals from the outside world into an electrical form that can be interpreted by the nervous system. In the nose, the sensory transducers are olfactory sensory neurons; in the ear, auditory hair cells; and in the eye, photoreceptors.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Actively secreting thyroid follicles are lined by which type of epithelium?", "options": [{"label": "A", "text": "Simple Squamous", "correct": false}, {"label": "B", "text": "Simple Cuboidal", "correct": false}, {"label": "C", "text": "Simple Columnar", "correct": true}, {"label": "D", "text": "Stratified Cuboidal", "correct": false}], "correct_answer": "C. Simple Columnar", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Simple Columnar This higher magnification of the thyroid gland shows individual thyroid follicles with secretory colloid material. The height of the follicular cells depends on the function of the individual follicles. In active follicles, the epithelium is cuboidal. In less active follicles, the epithelial cells appear flattened. All thyroid follicles are filled with the colloid, some of which show retraction from the follicular wall or distortion as a result of chemicals used in slide preparation. The simple columnar epithelium is associated with increased secretions from the Less active glands are lined by simple cuboidal epithelium.</p>\n<p><strong>Highyeild:</strong></p><p>The follicular cells secrete two hormones that influence the rate of metabolism. Iodine is an essential constituent of these hormones. One hormone containing three atoms of iodine in each molecule is called triodothyronine or T3. The second hormone containing four atoms of iodine in each molecule is called tetraiodothyronine, T4, or thyroxine. T3 is much more active than T4. Thyroid follicles</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Simple Squamous Option: B. Simple Cuboidal Option: D. Stratified Cuboidal Actively secreting thyroid follicles are lined by simple columnar epithelium, so options A, B and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>C-cells (Parafollicular Cells) They are also called clear cells, or light cells. The cells are polyhedral, with oval eccentric nuclei. Typically, they lie between the follicular cells and their basement membrane. They may, however, lie between adjoining follicular cells; but they do not reach the lumen. In some species, many parafollicular cells may lie in the connective tissue between the follicles and may be arranged in groups.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are true about the esophagus except:", "options": [{"label": "A", "text": "Lined by stratified squamous epithelium", "correct": false}, {"label": "B", "text": "Muscularis externa has an inner circular and outer longitudinal muscle layer", "correct": false}, {"label": "C", "text": "Middle third contains both skeletal and smooth muscle", "correct": false}, {"label": "D", "text": "Lower third contains only skeletal muscle", "correct": true}], "correct_answer": "D. Lower third contains only skeletal muscle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lower third contains only skeletal muscle The lower third contains only smooth muscle.</p>\n<p><strong>Highyeild:</strong></p><p>The outer wall of the esophagus, the muscularis externa, contains both skeletal and smooth muscle fibres. So, the upper third of the esophagus is in voluntary control. In the upper third of the esophagus, both layers of the muscularis externa contain striated skeletal muscle fibres. In the middle third of the esophagus, the muscularis externa contains a mixture of both skeletal and smooth muscle fibres, whereas, in the lower third of the esophagus, both layers are smooth muscle fibres.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Lined by stratified squamous epithelium Option: B. Muscularis externa has an inner circular and outer longitudinal muscle layer Option: C. Middle third contains both skeletal and smooth muscle The lower third of the esophagus has smooth muscle fibres, so Options A, B and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The esophageal submucosal gland (SMG) is located underneath the esophageal muscularis mucosa. It consists of mucous cells with or without a minor serous component and produces acid mucins and bicarbonate. The duct penetrates through the mucosa to open into the esophageal lumen.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Centroacinar cells are present in:", "options": [{"label": "A", "text": "Pancreas", "correct": true}, {"label": "B", "text": "Parotid gland", "correct": false}, {"label": "C", "text": "Prostate", "correct": false}, {"label": "D", "text": "None", "correct": false}], "correct_answer": "A. Pancreas", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pancreas Centroacinar cells are found in the Centroacinar cells are concerned with active secretion from the exocrine pancreas.</p>\n<p><strong>Highyeild:</strong></p><p>A pancreatic islet (of Langerhans) is illustrated at a higher magnification. The endocrine cells of the islet are arranged in cords and clumps, between which are found fine connective tissue fibres and an extensive capillary network. A thin connective tissue capsule separates the endocrine pancreatic islet from the surrounding exocrine serous acini. Some of the serous acini exhibit centrally located centroacinar cells, which form the initial part of the duct system that leads to the excretory intercalated duct. In contrast to secretory acini in other glands, there are no myoepithelial cells surrounding the secretory acini. Centroacinar cells</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Parotid gland Option: C. Prostate Option: D. None Centroacinar cells are found in the pancreas, so options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Distinguishing features of the parotid, submandibular, and sublingual salivary glands Parotid gland Submandibular gland Sublingual gland Location Near the ear Below the mandible Below the tongue Development Ectodermal Endodermal Endodermal Size Largest (25 g) Smaller (10-20 g) Smallest (3-4 g) Shape Pyramidal shaped J-shaped Almond shaped Duct and its site of opening in oral cavity Parotid duct opens into vestibule of oral cavity opposite the second upper molar tooth Submandibular duct opens into the floor of oral cavity proper on summit of sublingual papilla at the side of frenulum of the tongue Series of ducts open into the floor of the oral cavity proper on the sublingual fold Secretomotor nerve supply • Through lesser petrosal nerve. • Preganglionic fibres arise from inferior salivatory nucleus. •Postganglionic fibres arise from otic ganglion. • Through chorda tympani • Preganglionic fibres arise from superior salivatory nucleus •Postganglionic fibres arise from submandibular ganglion. • Through chorda tympani nerve • Preganglionic fibres arise from superior salivatory nucleus •Postganglionic fibres arise from submandibular ganglion Nature of secretion Serous Both serous and mucus Mucus</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Within which part of the gastric glands, are the chief cells located?", "options": [{"label": "A", "text": "Gastric PIT", "correct": false}, {"label": "B", "text": "Neck", "correct": false}, {"label": "C", "text": "Isthmus", "correct": false}, {"label": "D", "text": "Fundus", "correct": true}], "correct_answer": "D. Fundus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fundus The base or fundus is the deep portion of the gastric gland, composed predominantly of chief (zymogenic) cells and a few parietal cells.</p>\n<p><strong>Highyeild:</strong></p><p>The gastric glands extend the length of the mucosa and in deeper regions, the gastric glands may branch. As a result, the gastric glands appear as transverse and oblique sections. Each gastric gland consists of three regions. At the junction of the gastric pit with the gastric gland is the isthmus, lined with surface epithelial cells and parietal cells. Lower in the gland is the neck, containing mainly mucous neck cells and some parietal cells. The base or fundus is the deep portion of the gland, composed predominantly of chief (zymogenic) cells and a few parietal cells. Chief cells are responsible for the main enzymatic secretion from the pancreas. Gastric gland</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Gastric PIT The gastric pits are lined by a number of different cell types which contribute to the overall function of the stomach: Goblet cells – secrete mucus to form a protective layer around the stomach lining. Parietal cells – secrete hydrochloric acid which is responsible for creating a low-pH environment in the stomach. Option: B. Neck Lower in the gland is the neck, containing mainly mucous neck cells and some parietal cells. Option: C. Isthmus At the junction of the gastric pit with the gastric gland is the isthmus, lined with surface epithelial cells and parietal cells.</p>\n<p><strong>Extraedge:</strong></p><p>Cells of the gastric glands Secretory products Surface mucous cells Mucin in an alkaline fluid Mucous neck cells Mucin in an acidic fluid Parietal cells HCI & intrinsic factor Chief cells Pepsinogen & lipase G cells/enteroendocrine cells Gastrin</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Lining cells of the respiratory epithelium include all the following except:", "options": [{"label": "A", "text": "Kulchitsky Cells", "correct": false}, {"label": "B", "text": "Clara cells", "correct": false}, {"label": "C", "text": "Brush cells", "correct": false}, {"label": "D", "text": "Langerhans cells", "correct": true}], "correct_answer": "D. Langerhans cells", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Langerhans cells Langerhans cells are found in the epidermis of the They act as antigen-presenting cells.</p>\n<p><strong>Highyeild:</strong></p><p>Cells in the Respiratory Epithelium: Ciliated columnar cells are the most common and extend the thickness of the epithelium and sweep the surface. Goblet cells are numerous in airways and secrete protective mucus, but decrease in distal parts. Basal cells are close to the basal lamina, do not reach the surface, and serve as stem cells. Brush cells are less numerous, contact afferent axons, and may function as receptor cells. Small granule cells (Kulchitsky cells) contain granules and are analogous to enteroendocrine cells (DNES). Clara Cells: Replace goblet cells and become predominant cells in terminal and respiratory bronchioles. They secrete surfactant-like lipoprotein components that break down mucus stickiness and reduce surface tension.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Kulchitsky Cells Option: B. Clara cells Option: C. Brush cells Options A, B and C are present in respiratory epithelium.</p>\n<p><strong>Extraedge:</strong></p><p>A Langerhans cell ( LC ) is a tissue-resident macrophage of the skin once thought to be a resident dendritic cell. These cells contain organelles called Birbeck granules. They are present in all layers of the epidermis and are most prominent in the stratum spinosum. They also occur in the papillary dermis, particularly around blood vessels, as well as in the mucosa of the mouth, foreskin, and vaginal epithelium. They can be found in other tissues, such as lymph nodes, particularly in association with the condition Langerhans cell histiocytosis (LCH).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Hassall's corpuscles are seen in:", "options": [{"label": "A", "text": "Thymus", "correct": true}, {"label": "B", "text": "spleen", "correct": false}, {"label": "C", "text": "Lymph node", "correct": false}, {"label": "D", "text": "Appendix", "correct": false}], "correct_answer": "A. Thymus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thymus The thymic (Hassall’s) corpuscles are oval structures consisting of round or spherical aggregations (whorls) of flattened epithelial cells, located in the thymus gland.</p>\n<p><strong>Highyeild:</strong></p><p>Histology of thymus Made up of lymphoid tissue & not arranged in the form of follicles. The thymic lymphocytes in the cortex form dense aggregations. In contrast, the medulla contains only a few lymphocytes but more epithelial reticular cells. The thymic (Hassall’s) corpuscles are oval structures consisting of round or spherical aggregations (whorls) of flattened epithelial cells. The thymic corpuscles also exhibit calcification or degeneration centres that stain pink or eosinophilic. Whereas Subcapsular (marginal) sinuses are a feature of lymph nodes. Thymus gland histological slide</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. spleen Option: C. Lymph node Option: D. Appendix The thymic (Hassall’s) corpuscles are oval structures consisting of round or spherical aggregations (whorls) of flattened epithelial cells, located in the thymus gland, so options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The blood-thymus barrier is a functional and selective barrier separating T-lymphocytes from blood and cortical capillaries in the cortex of the thymus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the marked layer in the given histological section:", "options": [{"label": "A", "text": "Inner Plexiform Layer", "correct": false}, {"label": "B", "text": "Outer plexiform layer", "correct": false}, {"label": "C", "text": "Inner limiting layer", "correct": true}, {"label": "D", "text": "Outer limiting layer", "correct": false}], "correct_answer": "C. Inner limiting layer", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391601762-QTDA036027IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inner limiting layer This layer separates the nerve fibre layer from vitreous humor. The internal limiting membrane (ILM) is the basement membrane at the ocular vitreoretinal interface.</p>\n<p><strong>Highyeild:</strong></p><p>Layers of retina Eye: layers of retina and choroid. Stain: Masson trichrome. >100 This high-magnification photomicrograph illustrates the photosensitive retina. The choroid (1) is a vascular outer layer with loose connective tissue and melanocytes that is situated adjacent to the outermost retinal layer-the single-cell, pigment epithelium (2) layer. • The light-sensitive rods and cones (3) form the next layer, which is separated from the dense outer nuclear layer (4) by a thin outer limiting membrane (5). Deep to the outer nuclear layer (4) is a clear area of synaptic connections, the fibre plexiform layer(6). The dense layer of cell bodies of the integrating neurons forms the inner nuclear layer (7), which is adjacent to the clear inner plexiform layer (8) in whose layer the axons of the integrating neurons form synaptic connections with axons of the neurons that form the optic tract. The cell bodies of the optic tract neurons form the ganglion cell layer (9), and their afferent axons form the light-staining optic nerve fibre layer (10). The innermost layer of the retina is the inner limiting membrane (11), which separates the retina from the vitreous body of the eyeball.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Inner Plexiform Layer The inner plexiform layer ( inner synaptic layer) consists of synaptic connections between the axons of bipolar cells and the dendrites of ganglion cells. Option: B. Outer plexiform layer The outer plexiform layer (OPL; also outer synaptic layer) has a wide external band composed of inner fibres of rods and cones and a narrower inner band consisting of synapses between photoreceptor cells and cells from the inner nuclear layer. Option: D. Outer limiting layer The outer limiting membrane (OLM) is considered to play a role in maintaining the structure of the retina through mechanical strength. However, the observation of junction proteins located at the OLM and its barrier permeability properties may suggest that the OLM may be part of the retinal barrier.</p>\n<p><strong>Extraedge:</strong></p><p>The human retina has two types of photoreceptors to gather light namely rods and cones. While rods are responsible for vision at low light levels, cones are responsible for vision at higher light levels. The light levels where both are functional are known as mesopic.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Invasive ductal cancer is the most common breast cancer histological type, comprising 70–80% of all cases. Invasive breast cancers usually are epithelial tumours of ductal or lobular origin. Which of the following epithelia line the lactiferous ducts?", "options": [{"label": "A", "text": "Pseudostratified", "correct": false}, {"label": "B", "text": "Simple squamous", "correct": false}, {"label": "C", "text": "Stratified cuboidal", "correct": true}, {"label": "D", "text": "Stratified squamous", "correct": false}], "correct_answer": "C. Stratified cuboidal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Stratified cuboidal The lactiferous duct is lined by a two-cell layered cuboidal epithelium.</p>\n<p><strong>Highyeild:</strong></p><p>Lactiferous ducts draining each lobe of the breast pass through the nipple and open onto its tip as up to 20 orifices. Close to their openings on the nipple, the stratified cuboidal epithelial lining of the lactiferous ducts is replaced by keratinized stratified squamous epithelium, continuous with the epidermis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Pseudostratified Option: B. Simple squamous Option: D. Stratified squamous All other epithelial choices - A, B and D are not found in the breast tissue and are thus incorrect. The pseudostratified epithelium is found in the respiratory epithelium.</p>\n<p><strong>Extraedge:</strong></p><p>Polymastia (supernumerary breasts) and polythelia (supernumerary nipples) may develop in males and females anywhere along the length of the mammary ridges (milk lines).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 38 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 14-year-old boy comes to an emergency department, her father told her that during a football game, he had met an injury, and after that, he complained of severe pain on the posterior abdominal wall of the right side, mainly in the hypochondriac and lumbar region. On examination, the doctor found tenderness in the area below the 12th rib, and pain increased while pressing this region. What is your diagnosis?", "options": [{"label": "A", "text": "Injury to spleen", "correct": false}, {"label": "B", "text": "Injury to the right kidney", "correct": true}, {"label": "C", "text": "Injury to the left kidney", "correct": false}, {"label": "D", "text": "Injury to pancreas", "correct": false}], "correct_answer": "B. Injury to the right kidney", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Injury to the right kidney As because the pain is felt in the region of renal angle [angle between 12th rib and outer border of erector spinae muscle ], commonly injured in cases of lower thoracic cage injury, and tenderness is felt here on inspiration.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect as the spleen Is present in the left side of the abdomen. Option: C. Incorrect, as the question mentioned right-sided pain and injury, so the left kidney is not injured. Option: D. Incorrect as the pancreas is present on the left side of the body.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 42-year-old lady was diagnosed with pneumothorax leading to respiratory distress. She had a history of renal surgery one year back, following which she started having this respiratory distress. She has no history of respiratory problems before the surgery, nor does she have any relevant family history. During investigation 12th rib was not found, but the 11th rib was found normal. What may be the possible cause of her symptoms?", "options": [{"label": "A", "text": "Rupture of the lungs and collection of blood in the pleural cavity, which leads to her symptoms", "correct": false}, {"label": "B", "text": "Due to a fracture of their 11th rib leading to pleural effusion, which leads to her symptoms", "correct": false}, {"label": "C", "text": "The 11th rib was mistaken as the 12th rib during surgery, leading to a rupture of the pleural cavity, which led to her symptoms.", "correct": true}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "C. The 11th rib was mistaken as the 12th rib during surgery, leading to a rupture of the pleural cavity, which led to her symptoms.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The 11th rib was mistaken as the 12th rib during surgery, leading to a rupture of the pleural cavity, which led to her symptoms. In surgical exposure of the kidney, when the 12th rib is absent or too small, sometimes the 11th rib is mistaken as the 12th one, and so the chances of damaging the pleural cavity increase, leading to pneumothorax condition</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect as pneumothorax means leakage of air in the pleural cavity, not blood. Option: B. Incorrect as pneumothorax means leakage of air in the pleural cavity, not pleural effusion.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 42-year-old male complained of severe pain in the lower abdominal region; the pain starts in the loin region and radiates down the groin. Recently on examination in the nephrology department, he was diagnosed with ureteric stones. Which is the most likely site of the stone to get impacted in the ureters in this patient?", "options": [{"label": "A", "text": "Point of the crossing of the ureter by the broad ligament of the uterus", "correct": false}, {"label": "B", "text": "While passing on the tip of the transverse process of vertebra", "correct": false}, {"label": "C", "text": "At the site of enlargement of the uterine artery", "correct": false}, {"label": "D", "text": "Point of the crossing of the ureter by ductus deferens", "correct": true}], "correct_answer": "D. Point of the crossing of the ureter by ductus deferens", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Point of the crossing of the ureter by ductus deferens [Point of the crossing of the ureter by ductus deferens as because the ureteric stones are liable to become impacted at one of the normal constriction sites of the ureter] These constriction sites have less diameter as compared to other areas of ureters so stones can be easily lodged here. Pelviureteric junction</p>\n<p><strong>Highyeild:</strong></p><p>Normal constriction sites of ureters are – At the At the brim of the lesser pelvis Point of the crossing of the ureter by ductus deferens or broad ligament of uterus During oblique passage through the bladder wall At its opening in the lateral angle of the trigone</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Incorrect as the case is of a male patient, and the broad ligament is found in females Option: B. Incorrect because ureters pass medially on the tip of the transverse process, so it was not in direct contact with the vertebra so that no compression can occur through it in typical Option: C. Incorrect as the uterine artery is absent in males.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 42-Year-old male patient complained of severe pain in the Loin, which radiates along the scrotum and inner side of the thigh. After a radiological examination, it was found that he had ureteric stones. Scrotum was normal, having no inflammation. The possible reason for the radiating pain in this case is.", "options": [{"label": "A", "text": "Due to joint cutaneous innervation by the T11-l2 segment", "correct": true}, {"label": "B", "text": "Due to the inflammation present in the scrotum", "correct": false}, {"label": "C", "text": "Due to standard nerve supply by renal, aortic, and hypogastric plexus to these areas", "correct": false}, {"label": "D", "text": "All of the above", "correct": false}], "correct_answer": "A. Due to joint cutaneous innervation by the T11-l2 segment", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Due to joint cutaneous innervation by the T11-l2 segment In cases of ureteric stones, severe pain in cases of ureteric stones occurs in the loin area and radiates towards the groin, scrotum, or labium majus and inner side of the thigh Due to standard cutaneous supply to these areas along with ureter by t11-l2 segment]</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Incorrect as the scrotum on examination was found to be expected with no inflammation Option: C. Incorrect as renal, aortic, and hypogastric plexuses do not supply the scrotum and inner side of the thigh. Option: D. Incorrect, as all the given statements need to be corrected.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A girl with Turner's syndrome is brought to the physician complaining of nausea and pain in the left side of the abdomen. The following is the MRI scan of the patient's abdomen. What is the probable diagnosis?", "options": [{"label": "A", "text": "Splenomegaly", "correct": false}, {"label": "B", "text": "Pancreatitis", "correct": false}, {"label": "C", "text": "Horseshoe kidney", "correct": true}, {"label": "D", "text": "Annular pancreas", "correct": false}], "correct_answer": "C. Horseshoe kidney", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391800639-QTDA006005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Horseshoe kidney The patient has a congenital defect in her kidney known as the horseshoe kidney, wherein the lower parts of both kidneys are fused . It is the most common congenital anomaly of kidneys. This has increased in people with chromosomal defects such as Turner’s and Down’s syndrome. Horseshoe kidney is a congenital anomaly of the formation of kidneys. The symptoms include frequent UTIs, periodic reexamination, nausea, foul-smelling urine, etc. The patient complains of pain on the left side of the abdomen because of the mild ischemia of the left side of the transverse and descending colon. This is because the ascent of the kidney to its normal position is interrupted by the inferior mesenteric artery (the isthmus of the horseshoe kidney is the blockage), and the street is compressed. This artery is responsible for the blood supply of the hindgut. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Splenomegaly is the enlargement of the spleen in cases of increased hemolysis and some cancers. The spleen is an intraperitoneal organ present behind the stomach (stomach bed) on the left side. The MRI scan doesn’t indicate any anomalies on the left side. Hence, it is the wrong answer. Option: B. Pancreatitis is the inflammation of the pancreas. Pancreatitis may start suddenly and last for days, or it can occur over many years. It has many causes, including gallstones, heavy alcohol use, etc. The symptoms include upper abdominal pain, nausea, and vomiting. Since the pain is elicited on the left side and MRI doesn’t indicate it, the answer is wrong. Option: D. Annular pancreas is a congenital defect of the joining of the ventral and dorsal heads of the pancreas. The symptoms include early satiety and nausea due to duodenal atresia. Since the patient doesn’t complain of these symptoms and there is no radiological evidence of the defect, it is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A sixty-year-old man consults a physician complaining of sharp intermittent pain in the side of the lower abdomen. He also complains of hematuria, nausea, sweating, vomiting, and malaise. Blood tests indicate an elevated urea and calcium level. The following Image shows the patient's Noncontrast CT scan. What is the probable diagnosis?", "options": [{"label": "A", "text": "Nephrolithiasis", "correct": true}, {"label": "B", "text": "Pyelonephritis", "correct": false}, {"label": "C", "text": "Renal tumors", "correct": false}, {"label": "D", "text": "Renal infarction", "correct": false}], "correct_answer": "A. Nephrolithiasis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391801848-QTDA006006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Nephrolithiasis Nephrolithiasis, also known as renal calculi, is a disease affecting the urinary tract. Kidney stones are small deposits made of calcium, phosphate, and other components of foods that build up in the kidneys. They usually result in hematuria. Nephrolithiasis is also known as renal calculi, a disease that also affects the urinary tract. They usually result in hematuria. They are typically diagnosed by ultrasound, intravenous pyelography (IVP), an NCCT scan (Investigation of choice), and blood tests indicating increased calcium and urea content. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Pyelonephritis is the inflammation of the kidney that is usually due to a bacterial infection. The symptoms include fever, tenderness, nausea, burning sensation while urinating, and frequent urination. It doesn’t increase blood calcium content. Hence, it is the wrong answer. Option: C. Renal tumors are abnormal growths in the kidney. These masses may be benign or malignant. They mainly don’t elevate the blood urea level. They also don’t elicit sharp pain. Hence, it is the wrong answer. Option: D. Renal infarction results from an interruption in the regular blood supply to part of or the entire kidney. The two major causes of renal infarction are thromboembolism and in situ thrombosis. They don’t increase the blood urea and calcium level, but they increase LDH levels. Hence, it is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A young man in his twenties consults a physician as he feels a mass in his abdomen on standing. He also complains of frequent hematuria. The symptoms are relieved on lying down. General examination shows an abnormal renal angle examination. What is the diagnosis?", "options": [{"label": "A", "text": "Polycystic Kidney", "correct": false}, {"label": "B", "text": "Nephritis", "correct": false}, {"label": "C", "text": "Horseshoe kidney", "correct": false}, {"label": "D", "text": "Nephroptosis", "correct": true}], "correct_answer": "D. Nephroptosis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Nephroptosis The clinical vignette comes to a diagnosis of nephroptosis. It is a congenital condition with no support for the kidney. Hence, it freely floats in the abdominal cavity and is seen as a mass on standing; the renal angle is the angle between the 12th rib and the major psoas muscle for palpating the kidney; it is abnormal here due to the free-floating nature . The symptoms include hematuria, proteinuria, nausea, a feeling of weight in the abdomen, flanking pain on the affected side, vomiting, hypertension, etc.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Polycystic kidney is a congenital anomaly; there are several urine-filled pouches on the kidney surface. It causes hypertension, but it gives a regular renal angle examination. Hence, it is the wrong answer. Option: B. Nephritis is also known as glomerulonephritis and is the kidney's inflammation of the nephrons. It causes cloudy, pus-filled urine and doesn’t show abnormal renal angle examination. Hence, it is the wrong answer. Option: C. Horseshoe kidney is another congenital anomaly wherein both sides' kidneys are joined inferiorly. It usually doesn’t cause any severe problems. In some cases, it can cause ischemia of the part of the colon supplied by the inferior mesenteric artery. It doesn’t drive. The symptoms aren’t relieved on lying down. Hence, it is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "All are fibrous joints except?", "options": [{"label": "A", "text": "Gomphosis", "correct": false}, {"label": "B", "text": "Schindylesis", "correct": false}, {"label": "C", "text": "Syndesmosis", "correct": false}, {"label": "D", "text": "Symphysis", "correct": true}], "correct_answer": "D. Symphysis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Symphysis Symphysis refers to the secondary cartilaginous joints Eg. Symphysis pubis, symphysis menti etc. Fibrous Joint Classified into Sutures, syndesmoses and gomphosis. Suture: Found in the skull.</p>\n<p><strong>Highyeild:</strong></p><p>Symphyses are secondary cartilaginous joints composed of fibrocartilage (also known as fibrocartilaginous joints ). They are considered amphiarthroses, allowing only slight movement and are all found at the skeletal midline. Examples symphysis pubis between the pubic bones medially manubriosternal joint between the sternal body and the manubrium xiphisternal joint: in most, becomes synostosis by the fifth decade symphysis intervertebralis: comprises the anterior and posterior longitudinal ligaments and the intervertebral discs sacrococcygeal symphysis symphysis mandibulae (symphysis mentalis): midline joint between the half bodies of the hemi mandibles.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Gomphoses: also known as peg and socket A gomphosis is a fibrous mobile peg-and-socket joint. The roots of the teeth (the pegs) fit into their sockets in the mandible and maxilla and are the only examples of this type of joint. Option: B. Schindylesis – Sphenovomerine vomero-sphenoidal Joint This fibrous suture joint can be found between the vomer and the perpendicular plate of the ethmoid bone and between the vomer and the gap between the maxilla and palatine. Option: C. Syndesmosis: Bones are connected by interosseous ligaments or membranes. A syndesmosis is a slightly mobile fibrous joint in which bones such as the tibia and fibula are joined together by connective tissue. An example is the distal tibiofibular joint. Injuries to the ankle syndesmosis are commonly known as a \"high ankle sprain\".</p>\n<p><strong>Extraedge:</strong></p><p>Summary of Joint Classification Structural Class Characteristics Types Mobility Fibrous Bones united by collagen fibres 1. Suture 2. Syndesmosis 3. gomphosis 1. Immobile (synarthrosis) 2. Slightly moveable (amphiarthrosis) 3. Immobile Cartilaginous The bone ends united by cartilage 1. Synchondrosis (hyaline) 2. Symphysis (fibrocartilage 1. Immobile 2. Slightly moveable Synovial The bone ends covered with articular cartilage and enclosed within a capsule lined with a synovial membrane 1. Plane 2. Hinge 3. Pivot 4. Condyloid 5. Saddle 6. Ball and socket Freely moveable (diarthrosis), which depends on joint design</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient presents to the OPD with weakness of hip adduction and sensory deficits along the medial thigh region. On performing a thorough clinical examination and radiological imaging, a diagnosis of pelvic appendicitis was made. Which areas are likely to transmit the nerve involved in this condition?", "options": [{"label": "A", "text": "1", "correct": false}, {"label": "B", "text": "2", "correct": true}, {"label": "C", "text": "3", "correct": false}, {"label": "D", "text": "4", "correct": false}], "correct_answer": "B. 2", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1685615185084-QTDA070002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2 The clinical history suggests the involvement of OBTURATOR NERVE. This nerve passes through the obturator foramen marked as “2”. Damage to this nerve causes weakness of hip adduction and sensory deficits along the medial thigh.</p>\n<p><strong>Highyeild:</strong></p><p>Structures passing through the Greater sciatic foramen : Nerves: Vessels: Above piriformis muscle 1. Superior gluteal nerves 2. Superior gluteal vessels. 3. Piriformis muscle. Belew piriformis muscle 4. Inferior gluteal nerves 5. Sciatic nerve. 6. Posterior cutaneous nerve of the thigh (superficialis) 7. Nerve to quadratus femoris. 8. Nerve to obturator internus. 9. Pudendal Nerve. 10. Inferior gluteal vessels. 11. Internal pudendal vessels. Greater and Lesser Sciatic foramen of Hip</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A and C. are apertures of the greater sciatic foramen formed due to the Piriformis muscle passing through it. From 1 passes the superior gluteal nerves and vessels From 3 pass the inferior gluteal nerves and vessels sciatic nerve From 4 pass the PIN structures</p>\n<p><strong>Extraedge:</strong></p><p>The following pass through the Lesser Sciatic foramen : the tendon of the obturator internus. internal pudendal vessels. pudendal nerve. nerve to the obturator internus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The Pudendal nerve supplies sensory branches to the lower vagina through inferior rectal and posterior labial branches. Therefore, in vaginal operations, general anaesthesia has been replaced by pudendal nerve block. Identify the site of the pudendal nerve block;", "options": [{"label": "A", "text": "Near the ischial spine over the Sacrospinous ligament", "correct": true}, {"label": "B", "text": "Near the ischial spine over the Sacrotuberous ligament", "correct": false}, {"label": "C", "text": "Near the ischial tuberosity over the Sacrospinous ligament", "correct": false}, {"label": "D", "text": "Near the ischial tuberosity over the Sacrotuberous ligament", "correct": false}], "correct_answer": "A. Near the ischial spine over the Sacrospinous ligament", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Near the ischial spine over the Sacrospinous ligament A pudendal nerve block aims to block the nerve as it enters the lesser sciatic foramen, 1 cm inferior and medial, relative to the attachment of the sacrospinous ligament to the ischial spine . Pudendal nerve Block The pudendal nerve passes about the sacrospinous The nerve is infiltrated near the ischial spine by a needle passed through the vaginal wall and then guided by a finger</p>\n<p><strong>Highyeild:</strong></p><p>The pudendal nerve is the main nerve of the perineum. It carries sensation from the external genitalia of both sexes and the skin around the anus and perineum, as well as the motor supply to various pelvic muscles, including the male or female external urethral sphincter and the external anal sphincter. Loss of sensation or faecal incontinence may result if damaged, most commonly by childbirth. The nerve may be temporarily anaesthetised, called pudendal anaesthesia or pudendal block.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Near the ischial spine over the Sacrotuberous ligament Option: C. Near the ischial tuberosity over the Sacrospinous ligament Option: D. Near the ischial tuberosity over the Sacrotuberous ligament A pudendal nerve block aims to block the nerve as it enters the lesser sciatic foramen, 1 cm is inferior and medial, relative to the attachment of the sacrospinous ligament to the ischial spine . Therefore Options B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The pudendal nerve is one of the two main branches that originate from the sacral plexus and the sciatic nerve . It arises in the pelvis close to the upper border of the sacrotuberous ligament and ischiococcygeus muscle. The pudendal nerve receives input from the primary ventral roots of S2–S4 in the sacral plexus, which converge to form the nerve adjacent to the lateral wall of the pelvic cavity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A couple went on a camping trip and discovered the skeletal remains of a human near their campsite. They contacted the police and sent a forensics team to the site. The forensic doctor examined the pelvic remains and claimed the skeleton belonged to a male human. Which of the following features will not belong to the pelvis of a male human?", "options": [{"label": "A", "text": "Small and deep pelvic cavity", "correct": false}, {"label": "B", "text": "Heart-shaped pelvic cavity", "correct": false}, {"label": "C", "text": "Short and wide Sacrum", "correct": true}, {"label": "D", "text": "Subpubic angle 50-60 degree", "correct": false}], "correct_answer": "C. Short and wide Sacrum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Short and wide Sacrum Sacrum is Long and narrow in males, while short and wide in females. Compared to a male pelvis, a female pelvis shows the following differences. The false pelvis is deep in males and shallow in females. The pelvic inlet is heart-shaped in males due to jutting forwards of the sacral promontory. In females, it is transversely oval. The pelvic cavity is smaller and deeper in males. In females, the pelvic cavity is roomier and shallower, i.e. distance between the inlet and outlet is shorter. The pelvic outlet is smaller, with ischial tuberosities turned inside in males. In females, the pelvic outlet is bigger with everted ischial tuberosities. Sacrum is longer and narrow in males, while it is shorter and wider in females. The subpubic angle is narrower, i.e. 50°-70° in males. The angle is wider, i.e. 80-90° in females. This is the most important difference (Figs 15.14a and b). The greater sciatic notch is wider in females (75%) than in males (50°). The acetabulum is large in males, and its diameter is approximately equal to the distance from its anterior margin to the pubic symphysis. The chilotic line extends from the iliopubic eminence to the iliac crest. In females, the pelvic part of the chilotic line is longer than the sacral part. The preauricular sulcus is more marked in females. Male and Female Pelvis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Small and deep pelvic cavity The pelvic cavity is smaller and deeper in males. In females, the pelvic cavity is roomier and shallower, i.e. distance between the inlet and outlet is shorter. Option: B. Heart-shaped pelvic cavity The pelvic inlet is heart-shaped in males due to jutting forwards of the sacral promontory. In females, it is transversely oval. Option: D. Subpubic angle 50-60 degree The subpubic angle is narrower, i.e. 50°-70° in males. The angle is wider, i.e. 80-90 degrees in females. This is the most essential difference.</p>\n<p><strong>Extraedge:</strong></p><p>Differences between the male and female pelvis Male Female General structure Heavy and thick Light and thin Articular surfaces Large Small Muscle attachments Well marked Indistinct False pelvis Deep Shallow Pelvic inlet Heart-shaped Oval Pelvic canal/cavity \"Long segment of a short cone,” i.e., long and tapered \"Short segment of a long cone,” i.e., short with almost parallel sides Pelvic outlet Comparatively small Comparatively large The first piece of sacrum The superior surface of the body occupies nearly half the width of the base of the sacrum The superior surface of the body occupies about one-third the width of the bottom of the sacrum Sacrum Long, narrow, with smooth forward concavity Short, wide, flat, curving forward in the lower part Sacroiliac articular facet (auricular surface) Extends up to the lower border of the third piece of sacrum Extends down only up to the upper edge of the third piece of sacrum Subpubic angle The angle between the inferior pubic rami <90° (angle between the middle and index fingers) 90° or more (angle between the thumb and the index finger) Inferior pubic ramus Presents a strong everted surface for attachment of the crus of the penis This marking is not present Acetabulum Large Small Ischial tuberosities Inturned Everted Obturator Foramen Larger and oval Smaller and triangular</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The following image represents ischial tuberosity and its attachments. Identify the correctly matched pair of attachments and their location.", "options": [{"label": "A", "text": "1-Semimembranosus and long head of biceps femoris", "correct": false}, {"label": "B", "text": "2-Semitendinosus", "correct": false}, {"label": "C", "text": "1-Adductor Magnus and Semitendinosus", "correct": false}, {"label": "D", "text": "4-Adductor Magnus", "correct": true}], "correct_answer": "D. 4-Adductor Magnus", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1685615185114-QTDA070005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4-Adductor Magnus The attachments on the ischial tuberosity are as follows: The superolateral area gives origin to the semimembranosus The inferomedial area to the semitendinosus and the long head of the biceps femoris The outer lower area of the adductor magnus The inner lower area is covered with fibrofatty tissue and a bursa that supports body weight in the sitting position. While standing, this area is covered by the gluteus maximus muscle. The attachments on the ischial tuberosity</p>\n<p><strong>Highyeild:</strong></p><p>Muscles of the Back of the thigh Muscle Origin Insertion 1. Semitendinosus It is so named because it is muscular in the upper part and has a long tendon of insertion. It lies posteromedially in the thigh, superficial to the semimembranosus From the inferomedial impression on the upper part of the ischial tuberosity, in common with the long head of the biceps femoris Into the upper part of the medial surface of the tibia behind the sartorius and the gracilis 2. Semimembranosus It is so named because it has a flat tendon of origin. It lies posteromedially in the thigh, deep the semitendinosus From the superolateral impression on the upper part of the ischial tuberosity Into the groove on the posterior surface of the medial condyle of the tibia. Expansions from the tendon form the oblique popliteal, ligament, and the fascia covering the popliteus 3. Biceps femoris It has two heads of origin-long and short. It lies posterolaterally in the thigh a. Long head: From the inferomedial impression on the upper part of the ischial tuberosity; in common with the semitendinosus, and also from the lower part of the sacrotuberous ligament b. Short head: From the lateral lip of the linea aspera between the adductor magnus and the vastus lateralis, from the upper two-thirds of the lateral supracondylar line, and from the lateral intermuscular septum The tendon is folded around by the fibular collateral ligament. It is inserted into the head of the fibula in front of its apex or styloid process 4. Adductor magnus (see Fig. 4.1b) This is the largest muscle of this compartment. Because of its double nerve supply, it is called a hybrid muscle a. Lower lateral part of the ischial tuberosity b. Ramus of the ischium c. The lower part of the inferior ramus of the pubis a. Medial margin of gluteal tuberosity b. Linea aspera c. Medial supracondylar line d. Adductor tubercle</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. 1-Semimembranosus and long head of biceps femoris The area 1 is the inferomedial area of the ischial tuberosity, to which the semitendinosus and the long head of the biceps femoris is attached. Option: B. 2-Semitendinosus The area 2 is the superolateral area which gives origin to the semimembranosus Option: C. 1-Adductor Magnus and Semitendinosus The area 1 is the inferomedial area of the ischial tuberosity, to which the semitendinosus and the long head of the biceps femoris is attached.</p>\n<p><strong>Extraedge:</strong></p><p>Nerve supply and actions of hamstring muscles Muscle Nerve supply Actions 1. Semitendinosus Tibial part of sciatic nerve (L5, S1, 2) Chief flexor of the knee and medial rotator of the leg in the semiflexed knee. Weak extensor of the hip 2. Semimembranosus Tibial part of the sciatic nerve (L5, S1, 2) Chief flexor of the knee and medial rotator of the leg in the semiflexed knee. Weak extensor of the hip 3. Biceps femoris a. Long head, by tibial part of sciatic nerve b. Short head, by common peroneal part of the sciatic nerve (L5, S1, 2) Chief flexor of the knee and lateral rotator of leg in the semiflexed knee. Weak extensor of the hip 4. Adductor magnus (hybrid muscle) Double nerve supply: Adductor part by posterior division of obturator nerve ; Hamstring part by tibial part of sciatic nerve Adductor part causes adduction of thigh; Ischial part helps in extension of hip and flexion of knee</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 15 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 12 year old boy presented to the OPD with pain around his right knee. He is the captain of the football team and the pain is limiting the movement of the boy on the field. The doctor advised an X-ray of the knee and diagnosed the child as having Osgood-Schlatter disease. This disease involves which of the following structures attached to the tibial tuberosity?", "options": [{"label": "A", "text": "Iliotibial Tract", "correct": false}, {"label": "B", "text": "Patellar ligament", "correct": true}, {"label": "C", "text": "Semimembranosus", "correct": false}, {"label": "D", "text": "Popliteus", "correct": false}], "correct_answer": "B. Patellar ligament", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Patellar ligament Osgood-Schlatter disease occurs due to repetitive use injury of the knee especially during puberty due to differential growth between the patellar tendon, bones, and muscles around the knee. It is an avulsion of the patellar tendon from the tibial tuberosity. Avulsion of Patellar tendon in Osgood-Schlatter disease</p>\n<p><strong>Highyeild:</strong></p><p>Osgood Schlatter disease , also known as osteochondrosis or traction apophysitis of the tibial tubercle, is a common cause of anterior knee pain in the skeletally immature athletic population.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Iliotibial tract is attached to the lateral condyle of the tibia Option: C. Semimembranosus is attached to a groove on the posterior surface of the medial condyle Option: D. Popliteus is inserted on the posterior surface in the triangular area above the Soleil line</p>\n<p><strong>Extraedge:</strong></p><p>OSD may result in an avulsion fracture, with the tibial tuberosity separating from the tibia (usually remaining connected to a tendon or ligament). This injury is uncommon because there are mechanisms that prevent strong muscles from doing damage. The fracture on the tibial tuberosity can be a complete or incomplete break. Type I: A small fragment is displaced proximally and does not require surgery. Type II: The articular surface of the tibia remains intact and the fracture occurs at the junction where the secondary center of ossification and the proximal tibial epiphysis come together (may or may not require surgery). Type III: Complete fracture (through the articular surface) including a high chance of meniscal damage. This type of fracture usually requires surgery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A taxi driver presented to the emergency department after suffering from a road traffic accident. On examination, it was noticed that the patient sustained a dashboard injury leading to damage to a particular structure attached to the intercondylar area of the tibia. This structure is responsible for restricting the external rotation of the tibia. Identify the involved structure.", "options": [{"label": "A", "text": "1", "correct": false}, {"label": "B", "text": "2", "correct": false}, {"label": "C", "text": "3", "correct": false}, {"label": "D", "text": "4", "correct": true}], "correct_answer": "D. 4", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393132811-QTDA071002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4 The patient’s history of dashboard injury and the restriction of external rotation point toward the diagnosis of PCL ( posterior cruciate ligament). It is the posterior-most structure attached to the tibial intercondylar area. Structures in the intercondylar area of Tibia</p>\n<p><strong>Highyeild:</strong></p><p>The PCL functions as one of the main stabilizers of the knee joint and serves primarily to resist excessive posterior translation of the tibia relative to the femur . The posterior cruciate ligament (PCL) is the strongest and largest intra-articular ligament in the human knee and the primary posterior stabilizer of the knee. The PCL also acts as a secondary stabilizer of the knee preventing excessive rotation specifically between 90° and 120° of knee flexion.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. It is the anterior horn of the medial meniscus Option: B . It is an Anterior cruciate ligament and is often torn as a part of sports injuries, The function of all is a restriction of hyperextension and internal rotation. Option: C. It is the posterior horn of the lateral meniscus.</p>\n<p><strong>Extraedge:</strong></p><p>The anterior cruciate ligament (ACL) is one of the two cruciate ligaments which stabilizes the knee joint by preventing excessive forward movements of the tibia or limiting rotational knee movements.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statements about fibula is false?", "options": [{"label": "A", "text": "Fibula violates the law of ossification because the secondary center of ossification which appears first does not fuse last", "correct": false}, {"label": "B", "text": "The secondary center appears first in the lower end because it is a traction epiphysis", "correct": true}, {"label": "C", "text": "Fibula is an ideal spare bone for a bone graft", "correct": false}, {"label": "D", "text": "If the foot gets caught in a hole in the ground, there is forcible abduction and external rotation, such as an injury leads to Pott’s fracture.", "correct": false}], "correct_answer": "B. The secondary center appears first in the lower end because it is a traction epiphysis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The secondary center appears first in the lower end because it is a traction epiphysis This is a false statement because the secondary center appears first in the lower end because it is pressure epiphysis (pressure epiphysis appears before traction epiphysis).</p>\n<p><strong>Highyeild:</strong></p><p>There are four types of epiphysis: Pressure epiphysis: The region of the long bone that forms the joint is a pressure epiphysis (e.g. the head of the femur, part of the hip joint complex). Pressure epiphysis assists in transmitting the weight of the human body and is the region of the bone that is under pressure during movement or locomotion. Traction epiphysis : The regions of the long bone which are non-articular, i.e. not involved in joint formation. Unlike pressure epiphyses, these regions do not assist in weight transmission. However, their proximity to the pressure epiphysis region means that the supporting ligaments and tendons attach to these areas of the bone. Traction epiphyses ossify later than pressure epiphyses. Examples of traction epiphyses are tubercles of the humerus (greater tubercle and lesser tubercle), and trochanters of the femur (greater and lesser). Atavistic epiphysis: A bone that is independent phylogenetically but is fused with another bone in humans. These types of fused bones are called atavistic, g. , the coracoid process of the scapula, which has been fused in humans, but is separate in four-legged animals. os trigonum (posterior tubercle of the talus) is another example of an atavistic epiphysis. Aberrant epiphysis: These epiphyses are deviations from the norm and are not always present. For example, the epiphysis at the head of the first metacarpal bone and at the base of other metacarpal bones. Four types of epiphysis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Upper epiphysis fuses last because this is the growing end of the bone. Option: C. Fibula is an ideal bone graft. Option: D. Pott’s fracture is a spiral fracture involving the lateral malleolus, medial malleolus, and posterior margin of the It often occurs when the foot is caught in a hole in the ground.</p>\n<p><strong>Extraedge:</strong></p><p>An epiphysis is one of the rounded ends or tips of a long bone that ossify from a secondary center of ossification. Between the epiphysis and diaphysis lies the metaphysis, including the epiphyseal plate (growth plate). At the joint, the epiphysis is covered with articular cartilage; below that covering is a zone similar to the epiphyseal plate, known as subchondral bone. The epiphysis is filled with red bone marrow, which produces erythrocytes (red blood cells).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient who underwent knee replacement surgery 1 week ago. The surgery went uneventfully and the patient was advised to bed rest. When the patient started to ambulate he noticed that he was unable to dorsiflex his foot. He went to see the doctor and the doctor conducted a thorough sensory and motor examination of the foot. He found that there was a loss of sensation in the first interdigital cleft of the foot. Which of the following muscles is not supplied by the nerve affected in this condition?", "options": [{"label": "A", "text": "Peroneus Tertius", "correct": false}, {"label": "B", "text": "Tibialis anterior", "correct": false}, {"label": "C", "text": "Extensor digitorum brevis", "correct": false}, {"label": "D", "text": "Peroneus brevis", "correct": true}], "correct_answer": "D. Peroneus brevis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Peroneus brevis The clinical scenario suggests an injury to the deep peroneal nerve during knee replacement surgery, This nerve supplies sensory supply to 1st interdigital cleft and supplies the muscles of the anterior compartment of the leg. Peroneus brevis(Option D) and Peroneus longus are muscles of the lateral compartment supplied by the superficial peroneal nerve; it also gives sensory supply to the dorsum of the leg and foot except for the 1st interdigital cleft.</p>\n<p><strong>Highyeild:</strong></p><p>Nerve supply and actions of muscles Muscle Nerve supply Actions 1. Tibialis anterior Deep peroneal nerve a. Dorsiflexor of foot b. Invertor of the foot (see Fig. 11.12) c. Keeps the leg vertical while walking on uneven ground d. Maintains medial longitudinal arch of the foot 2. Extensor hallucis longus Deep peroneal nerve Dorsiflexor of foot and extends metatarsophalangeal and interphalangeal joints of the big toe 3. Extensor digitorum longus Deep peroneal nerve Dorsiflexor of the foot. Extends metatarsophalangeal, proximal, and distal interphalangeal joints of 2nd-5th toes 4. Peroneus Tertius Deep peroneal nerve Dorsiflexor of foot and evertor of foot 5. Extensor digitorum brevis Lateral terminal branch of the deep peroneal nerve The medial tendon known as the extensor hallucis brevis extends the metatarsophalangeal joint of the big toe. The other three lateral tendons extend the metatarsophalangeal and interphalangeal joints of 2nd, the 3rd, and 4th toes, particularly in a dorsiflexed foot</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - The following muscles are supplied by deep peroneal nerve Option: A. Peroneus Tertius Option: B. Tibialis anterior Extensor hallucis longus Extensor digitorum longus Option: C. Extensor digitorum brevis</p>\n<p><strong>Extraedge:</strong></p><p>The deep fibular nerve (also known as deep peroneal nerve) begins at the bifurcation of the common fibular nerve between the fibula and upper part of the fibularis longus, passes inferno-medially, deep to the extensor digitorum longus, to the anterior surface of the interosseous membrane, and comes into relation with the anterior tibial artery above the middle of the leg; it then descends with the artery to the front of the ankle joint, where it divides into a lateral and a medial terminal branch.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A factory worker presented to the emergency department with a hand injury. The patient complained that while working his hand got stuck in a machine and got crushed. The patient was taken to the ER and salvage surgery was performed. The operating surgeon suggested that the nerve damage was very extensive and needed an autologous nerve graft to recover some degree of neural function. Which of the following areas is supplied by the nerve ideally suited for an autologous nerve graft?", "options": [{"label": "A", "text": "1", "correct": true}, {"label": "B", "text": "2", "correct": false}, {"label": "C", "text": "3", "correct": false}, {"label": "D", "text": "4", "correct": false}], "correct_answer": "A. 1", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393134719-QTDA071005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1 This is the region supplied by the sural nerve considered the ideal nerve for autologous nerve grafting.</p>\n<p><strong>Highyeild:</strong></p><p>The sural nerve (L4-S1) is a cutaneous sensory nerve of the posterolateral calf with cutaneous innervation to the distal one-third of the lower leg. Formation of the sural nerve is the result of either anastomosis of the medial sural cutaneous nerve and the sural communicating nerve , or it may be found as a continuation of the lateral sural cutaneous nerve traveling parallel to the medial sural cutaneous nerve. The sural nerve specifically innervates the cutaneous sensorium over the posterolateral leg and lower lateral ankle via lateral calcaneal branches. Cutaneous innervation of the back of the leg</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Saphenous nerve. The distal saphenous nerve is commonly known to provide cutaneous innervation of the medial side of the ankle and distally to the base of the great toe. Option: C. Medial calcaneal nerve. The medial calcaneal branches of the tibial nerve (internal calcaneal branches) perforate the laciniate ligament and supply the skin of the heel and medial side of the sole of the foot. Option: D. Peroneal communicating nerve. The peroneal communicating nerve originates in the popliteal fossa either from the lateral sural cutaneous nerve or directly from the common peroneal nerve. The nerve communicates with the medial sural cutaneous nerve to form the sural nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The sural nerve (L4-S1) is generally considered a pure cutaneous nerve of the posterolateral leg to the lateral ankle. The sural nerve originates from a combination of either the sural communicating branch and medial sural cutaneous nerve, or the lateral sural cutaneous nerve. This group of nerves is termed the sural nerve complex. There are eight documented variations of the sural nerve complex. Once formed the sural nerve takes its course midline posterior to posterolateral around the lateral malleolus. The sural nerve terminates as the lateral dorsal cutaneous nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 20 year old sportsperson presented to the emergency department after a sports injury. He collided with another player during the match and fell down clutching his knee. The patient exhibited pain along the medial aspect of the knee. A plain X-Ray of the knee reveals a fracture of the medial condyle of the tibia. The orthopedic surgeon classified it as a Schatzker type 4 fracture. Which of the following structures are not attached to the medial condyle of the tibia?", "options": [{"label": "A", "text": "Capsular ligament of the knee joint", "correct": false}, {"label": "B", "text": "Semimembranosus", "correct": false}, {"label": "C", "text": "Patellar ligament", "correct": false}, {"label": "D", "text": "Iliotibial tract", "correct": true}], "correct_answer": "D. Iliotibial tract", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Iliotibial tract Attachments of the medial condyle are capsular ligament of the knee joint semimembranosus medial patellar retinaculum Attachments of lateral condyle are iliotibial tract capsular ligament tendon of popliteus</p>\n<p><strong>Highyeild:</strong></p><p>The Schatzker classification system for tibial plateau fractures is widely used by orthopedic surgeons to assess the initial injury, plan management, and predict prognosis. The Schatzker classification divides tibial plateau fractures into six types: lateral plateau fracture without depression (type I), lateral plateau fracture with depression (type II), compression fracture of the lateral (type IIIA) or central (type IIIB) plateau, medial plateau fracture (type IV), bicondylar plateau fracture (type V), and plateau fracture with diaphyseal discontinuity (type VI).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Capsular ligament of the knee joint The capsular ligament of the knee joint is attached to both the medial and lateral condyles of the tibia. Option: B. Semimembranosus Semimembranosus is attached to the medial condyle of the tibia. Option: C. Patellar ligament The patellar ligament in the form of the medial patellar retinaculum is attached to the medial condyle of the tibia.</p>\n<p><strong>Extraedge:</strong></p><p>Management of type I, II, and III fractures centers on evaluating and repairing the articular cartilage. The fracture-dislocation mechanism of type IV fractures increases the likelihood of injury to the peroneal nerve or popliteal vessels. In type V and VI fractures, the location of soft-tissue injury dictates the surgical approach and the degree of soft-tissue swelling dictates the timing of definitive surgery and the need for provisional stabilization with an external fixator.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 25 year old soccer player presented to the OPD with pain around the knee joint. He claims that the pain has been slowly developing on the inside of his knee since the last game. On taking a thorough history he mentions that he often does not follow proper stretching exercises before the game. The attending doctor makes a diagnosis of anserine bursitis. Which of the following muscles do not form the boundaries of the anserine bursa?", "options": [{"label": "A", "text": "gracilis", "correct": false}, {"label": "B", "text": "Sartorius", "correct": false}, {"label": "C", "text": "Semimembranosus", "correct": true}, {"label": "D", "text": "Semitendinosus", "correct": false}], "correct_answer": "C. Semimembranosus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Semimembranosus The Semimembranosus muscle is attached to the posterior surface of the medial condyle of the Tibia.</p>\n<p><strong>Highyeild:</strong></p><p>The pes anserinus is where the tendons of the sartorius, gracilis, and semitendinosus join at the medial knee, into the anteromedial proximal tibia. Pes anserine bursitis may result from stress, overuse, obesity, and trauma to this area. An occurrence of pes anserine bursitis commonly is characterized by pain at the medial knee and upper tibial region, especially when climbing stairs, tenderness, and local swelling.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Gracilis Option: B. Sartorius Option: D. Semitendinosus Gracilis, Sartorius, and Semitendinosus form the boundaries of the anserine bursa.</p>\n<p><strong>Extraedge:</strong></p><p>Pes anserine bursitis is an inflammation of the bursa located between the shinbone (tibia) and three tendons of the hamstring muscle at the inside of the knee . It occurs when the bursa becomes irritated and produces too much fluid, which causes it to swell and put pressure on the adjacent parts of the knee.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The patient presented with loss of extension at the knee joint with decreased sensation over the anterior aspect of the thigh. The nerve damage is:", "options": [{"label": "A", "text": "Obturator", "correct": false}, {"label": "B", "text": "Femoral", "correct": true}, {"label": "C", "text": "Common peroneal", "correct": false}, {"label": "D", "text": "Tibial", "correct": false}], "correct_answer": "B. Femoral", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Femoral The femoral nerve supplies the extensors at the knee joint and skin over the anterior aspect of the thigh. Injury of the femur is uncommon but may be injured by a stab, gunshot wounds, during hip operations or a pelvic fracture leading to Motor loss Poor flexion at the hip joint because of paralysis of the iliacus and sartorius muscles. Inability to extend the knee because of paralysis of the quadriceps femoris. Sensory loss Over the anterior and medial aspects of the thigh. Over the medial side of the leg and foot up to the back of the great toe.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Obturator The obturator nerve arises from the lumbar plexus and provides sensory and motor innervation to the thigh. The obturator nerve : Provides motor innervation to the medial compartment of the thigh It is essential to the adduction of the thigh. Provides sensory innervation to the medial upper thigh and articular branches to the hip and knee. Option C. Common peroneal The common peroneal nerve is the smaller and terminal branch of the sciatic nerve, composed of the posterior divisions of L4, 5, S1, and 2. It passes forwards around the neck of the fibula within the substance of fibularis (peroneus) longus, where it terminates by dividing into the superficial and deep fibular (peroneal) nerves. Common peroneal nerve gives : The Genicular branches of the knee joint The Lateral cutaneous nerve of the calf A Sural communicating branch. The two terminal branches include Superficial peroneal nerve Deep peroneal nerve The superficial peroneal nerve supplies the leg's lateral (peroneal) compartment muscles . In addition, it supplies the skin over the lateral lower two-thirds of the leg and the whole of the dorsum of the foot except for the area between the 1st and 2nd toes, which is supplied by the deep peroneal nerve. The deep peroneal nerve runs with the anterior tibial vessels over the interosseous membrane into the anterior compartment of the leg and then over the ankle to the dorsum of the foot. It supplies the anterior compartment's muscles and provides a cutaneous supply to the area between the 1st and 2nd toes. Option D. Tibial The tibial nerve is the larger terminal branch of the two main muscular branches of the sciatic nerve. The tibial nerve provides innervation to the lower leg and foot muscles. Specifically: triceps surae (the two-headed gastrocnemius and soleus), plantaris, Popliteus, tibialis posterior, flexor digitorum longus and flexor hallucis longus. It also has articular and cutaneous branches.</p>\n<p><strong>Extraedge:</strong></p><p>At the foot level, the tibial nerve divides into the medial plantar nerve (MPN) and the lateral plantar nerve (LPN). The MPN supplies muscular branches to the big toe and the two toes next to it, and the LPN the other two toes. The sural nerve is a cutaneous branch of the tibial nerve that supplies the skin of the legs and feet.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 23-year-old man is admitted to the emergency department with a deep, bleeding stab wound of the pelvis. After the bleeding has been arrested, an MRI examination shows that the right ventral primary ramus of L4 has been transected. Which of the following problems will most likely be seen during physical examination?", "options": [{"label": "A", "text": "Reduction or loss of sensation from the medial aspect of the leg", "correct": true}, {"label": "B", "text": "Loss of the Achilles tendon reflex", "correct": false}, {"label": "C", "text": "Weakness of abduction of the thigh at the hip joint", "correct": false}, {"label": "D", "text": "Inability to evert the foot", "correct": false}], "correct_answer": "A. Reduction or loss of sensation from the medial aspect of the leg", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Reduction or loss of sensation from the medial aspect of the leg The ventral ramus of L4 contains both sensory and motor nerve fibers. Injury from a stab wound dermatome supplied by this segment. L4 dermatome supplies the medial aspect of the leg and foot.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Loss of the Achilles tendon reflex Loss of Achilles tendon reflex relates primarily to an S1 deficit. Option C. Weakness of abduction of the thigh at the hip joint The obturator internus, gluteus medius, and minimus are responsible for the abduction of the thigh and are innervated by nerves L4, L5, and S1 (with L5 usually dominant). Option D. Inability to evert the foot Nerves L5, S1, and S2 are responsible for eversion of the foot( S1 dominant)</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 30-year-old male suffered a Superior Gluteal Nerve Injury in a motorcycle crash in which his right lower limb was caught beneath the bike. He is stabilised in the emergency department. Later, he is examined and exhibits a waddling gait and a positive Trendelenburg sign. Which of the following was the position?", "options": [{"label": "A", "text": "Difficulty in standing from sitting sags when he attempts to stand with his weight supported just by the lower limb", "correct": false}, {"label": "B", "text": "The left side of the pelvis drops orld be this patient's most likely physical finding.", "correct": true}, {"label": "C", "text": "The right side of the pelvis droops or sags when he attempts to stand with his weight supported just by the left lower limb", "correct": false}, {"label": "D", "text": "Weakened flexion of the right hip", "correct": false}], "correct_answer": "B. The left side of the pelvis drops orld be this patient's most likely physical finding.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The left side of the pelvis drops orld be this patient's most likely physical finding. Injury to the Superior gluteal nerve results in characteristic motor loss and paralysis of the Gluteus Medius and Minimus. When the patient is asked to stand on the limb of the injured side, the pelvis descends on the opposite side, indicating a positive Trendelenburg sign. Injury to the right superior gluteal nerve would result in sagging of the left side of the pelvis when the affected individual stands on the right limb.</p>\n<p><strong>Highyeild:</strong></p><p>The gluteal or lurching gait that results from this injury is characterised by the pelvis drooping to the unaffected side when the opposite leg is raised. In stepping forward, the affected individual leans over the injured side when lifting the good limb off the ground. The uninjured limb is then swung forward. Trendelenburg sign</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Difficulty in standing from sitting position The Gluteus maximus is the muscle involved in standing from a sitting position and is innervated by the Inferior gluteal nerve. The Gluteus maximus and the hamstrings work together to extend the trunk from a flexed position by pulling the pelvis backwards ,e.g. standing up from a bent forward position. Option C. The right side of the pelvis droops or sags when he attempts to stand with his weight supported just by the left lower limb Injury to the left superior gluteal nerve would result in sagging of the right side of the pelvis when the affected individual stands on the left limb. Option D. Weakened flexion of the right hip Prime hip flexors are Iliacus and Psoas major muscles. The Femoral nerve innervates Iliacus, and the Lumbar plexus innervate the Psoas major via anterior branches of L1-L3 nerves.</p>\n<p><strong>Extraedge:</strong></p><p>Trendelenburg's sign is found in people with weak or paralysed hip abductor muscles, namely gluteus medius and gluteus minimus. I t is named after the German surgeon Friedrich Trendelenburg. It is often incorrectly referenced as the Trendelenburg test for vascular insufficiency in the lower extremities.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old male is treated at the hospital after he fell from his bicycle. Radiographic examination reveals fractures in both of tibia and fibula. On physical examination, the patient has a foot drop but normal eversion. Which of the following nerves is most likely injured?", "options": [{"label": "A", "text": "Tibial", "correct": false}, {"label": "B", "text": "Common fibular", "correct": false}, {"label": "C", "text": "Superficial fibular", "correct": false}, {"label": "D", "text": "Deep fibular", "correct": true}], "correct_answer": "D. Deep fibular", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deep fibular The deep fibular nerve is responsible for innervating the muscles of the anterior compartment of the leg, which are responsible for toe extension, foot dorsiflexion, and inversion . Injury to this nerve will result in foot drop and also loss of sensation between the first and second toes.</p>\n<p><strong>Highyeild:</strong></p><p>Deep Peroneal Nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Tibial Injury to the tibial nerve affects the posterior compartment muscles of the leg, which are responsible for palmar flexion and toe flexion, as well as the intrinsic muscles of the sole. Option B. Common fibular If the common fibular nerve were injured, eversion of the foot and plantar flexion would be lost in addition to dorsiflexion and inversion. Option C. Superficial fibular The superficial fibular nerve innervates the fibularis longus and brevis muscles, which provide eversion of the foot.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 46-year-old woman stepped on a broken wine bottle, and the sharp glass entered the posterior part of her foot. The patient was admitted to the hospital, and a physical examination concluded that her lateral plantar nerve had been transected. Which of the following conditions will most likely be confirmed by physical examination?", "options": [{"label": "A", "text": "Loss of sensation over the plantar surface of the third toe", "correct": false}, {"label": "B", "text": "Paralysis of the abductor hallucis", "correct": false}, {"label": "C", "text": "Paralysis of the interossei and adductor hallucis", "correct": true}, {"label": "D", "text": "Flexor hallucis brevis paralysis", "correct": false}], "correct_answer": "C. Paralysis of the interossei and adductor hallucis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Paralysis of the interossei and adductor hallucis Lateral Plantar nerve The lateral plantar nerve innervates the interossei and adductor hallucis These losses would be obvious when the patient attempts to abduct and adduct the toes. Sensations would be absent over the lateral side of the sole, little toe and half of the fourth toe.</p>\n<p><strong>Highyeild:</strong></p><p>Lateral plantar nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Loss of sensation over the plantar surface of the third toe Option B. Paralysis of the abductor hallucis Option D. Flexor hallucis brevis paralysis The Medial plantar nerve provides sensations over the plantar surface of the medial three-and-a-half-fourth toes. Also, it innervates the first lumbrical, abductor hallucis, flexor hallucis brevis, and flexor digitorum brevis.</p>\n<p><strong>Extraedge:</strong></p><p>Medial plantar nerve</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A radiographic examination of a woman with foot pain reveals Morton’s neuroma. What is the most typical location of this neuroma?", "options": [{"label": "A", "text": "Between the third and fourth metacarpophalangeal joints", "correct": true}, {"label": "B", "text": "Between the second and third metacarpophalangeal joints", "correct": false}, {"label": "C", "text": "Between the first and second metacarpophalangeal joints", "correct": false}, {"label": "D", "text": "Between the fourth and fifth metacarpophalangeal joints", "correct": false}], "correct_answer": "A. Between the third and fourth metacarpophalangeal joints", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Between the third and fourth metacarpophalangeal joints Morton’s neuroma most commonly involves compression (and possible enlargement) of an anastomosing branch that connects the medial and lateral plantar nerves between the third and fourth toes.</p>\n<p><strong>Highyeild:</strong></p><p>The pain of Morton’s neuroma can be severe. The medial plantar nerve provides sensations for the medial three-and-a-half toes; the lateral plantar nerves supply the little toe and half of the fourth toe. The neural interconnection between the transverse metatarsal ligament and the floor can be compressed. Women are 10 times more likely than men to be afflicted with this problem, most likely due to wearing shoes that put excessive stress on the forefoot. In about 80% of cases, the pain can be eased with different shoes or cortisone injections.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Between the second and third metacarpophalangeal joints Option C. Between the first and second metacarpophalangeal joints Option D. Between the fourth and fifth metacarpophalangeal joints Options B, C and D are not common sites for Morton's neuroma.</p>\n<p><strong>Extraedge:</strong></p><p>A neuroma is a benign nerve tissue tumour often associated with pain or specific types of various other symptoms. Neuromas commonly arise from non-neuronal nervous tissue after amputation or trauma or can be true neoplasms.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During a physical examination of a patient with a history of TIA (Transient ischaemic attack), it is found that the ankle jerk reflex is absent. Which of the following nerves is responsible for the reflex arc?", "options": [{"label": "A", "text": "Common Fibular", "correct": false}, {"label": "B", "text": "Superficial fibular", "correct": false}, {"label": "C", "text": "Deep fibular", "correct": false}, {"label": "D", "text": "Tibial", "correct": true}], "correct_answer": "D. Tibial", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tibial The tibial nerve mediates the ankle jerk reflex, elicited by tapping the Tendo Achilles with the reflex hammer.</p>\n<p><strong>Highyeild:</strong></p><p>The ankle jerk reflex , also known as the Achilles reflex , occurs when the Achilles tendon is tapped while the foot is dorsiflexed. It is a stretch reflex that tests the function of the gastrocnemius muscle and the nerve that supplies it. A positive result would be the foot jerking towards its plantar surface. The S1 spinal segment of the spinal cord mediates this reflex.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Common Fibular The common fibular nerve combines the superficial and deep peroneal nerve functions. Option B. Superficial fibular The superficial fibular nerve supplies the foot Evertor muscles of the lateral compartment of the leg and provides sensory supply for the dorsum of the foot. Option C. Deep fibular The deep fibular nerve innervates the foot extensor and inverter muscles in the anterior compartment of the leg and supplies skin between the first and second toes.</p>\n<p><strong>Extraedge:</strong></p><p>For Testing the power in muscle groups: Hip flexion ( L1, L2-iliopsoas-straight leg raise ) Knee flexion ( L5to S2-hamstrings- the patient tries to bend the knee while the examiner applies force to the leg to hold the knee in extension) Knee extension (L3, L4- quadriceps femoris -the patient attempts to keep the leg straight while the examiner applies a force to the leg to flex the knee joint) Ankle plantarflexion (S1, S2- the patient pushes the foot down while the examiner applies a force to the plantar surface of the foot to dorsiflex the ankle joint); miner applies a force to the plantar surface of the foot to dorsiflex the ankle joint) Ankle dorsiflexion (L4, L5 -the patient pulls the foot upward while the examiner applies a force to the dorsal aspect of the foot to plantarflex the ankle joint).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Gluteal intramuscular injections have given a 67-year-old patient a course of antibiotics after a major abdominal surgery. To avoid damaging the sciatic nerve during an injection, the needle should be inserted into which of the following areas?", "options": [{"label": "A", "text": "Over the sacrospinous ligament", "correct": false}, {"label": "B", "text": "Midway between the ischial tuberosity and the lesser trochanter", "correct": false}, {"label": "C", "text": "Midpoint of the gemelli muscles", "correct": false}, {"label": "D", "text": "Upper lateral quadrant of the gluteal region", "correct": true}], "correct_answer": "D. Upper lateral quadrant of the gluteal region", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Upper lateral quadrant of the gluteal region To avoid damaging the sciatic nerve during an intramuscular injection, the clinician should insert the needle in the upper lateral quadrant of the gluteal region. The inserted needle in the lower medial quadrant may damage the quadratus femoris's sciatic and posterior femoral cutaneous nerves.</p>\n<p><strong>Highyeild:</strong></p><p>Site for Intramuscular injection in Gluteal region</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Over the sacrospinous ligament The inserted needle over the sacrospinous ligament may damage the pudendal nerve and vessels. Option B. Midway between the ischial tuberosity and the lesser trochanter The inserted needle midway between the ischial tuberosity and the lesser trochanter may damage the sciatic and posterior femoral cutaneous nerves on the quadratus femoris. Option C. Midpoint of the gemelli muscles The midpoint of two gemelli muscles is challenging to locate and is not a suitable site for IM injection.</p>\n<p><strong>Extraedge:</strong></p><p>The deltoid muscle is the preferred injection site in children aged 3-18 when muscle mass is more developed. It is suitable for small-volume injections. The recommended volume is 1 ml; however, up to 2mls can be administered. The deltoid muscle is a rounded triangle shape. To landmark this site, the patient should be seated comfortably with their arm visible from the shoulder to the top of the elbow. Palpate the acromion (outer edge of the scapula) and trace an imaginary inverted triangle below the shoulder. The injection should be given 3-5 cm below the acromion, in the middle of the triangle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 17-year-old boy was stabbed during a group fight, resulting in the transection of the obturator nerve. Which of the following muscles is completely paralysed?", "options": [{"label": "A", "text": "Pectineus", "correct": false}, {"label": "B", "text": "Adductor magnus", "correct": false}, {"label": "C", "text": "Adductor longus", "correct": true}, {"label": "D", "text": "Biceps femoris", "correct": false}], "correct_answer": "C. Adductor longus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Adductor longus The adductor longus muscle is innervated by only the obturator nerve . Thus, an injury here could cause nerve damage resulting in Complete paralysed adductor longus.</p>\n<p><strong>Highyeild:</strong></p><p>The adductor longus arises from the body of the pubis inferior to the pubic crest and lateral to the pubic symphysis. It lies ventrally on the adductor magnus, and near the femur, the adductor brevis is interposed between these two muscles. Distally, the fibres of the adductor longus extend into the adductor canal. It is inserted into the middle third of the medial lip of the Linea aspera.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Pectineus The pectineus is innervated by both the obturator and femoral nerves. Option B. Adductor magnus The adductor magnus is innervated by the obturator nerve and the tibial part of the sciatic nerve. Option D. Biceps femoris The biceps femoris is innervated by the tibial portion (long head) and common peroneal portion (short head) of the sciatica nerve.</p>\n<p><strong>Extraedge:</strong></p><p>Adductor longus muscle actions are to adduct and internally rotate the thigh; it can also produce some degree of flexion/anteversion.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 21-year-old man was involved in a motorcycle accident, destroying the groove in the lower surface of the cuboid bone. Which of the following muscle tendons is most likely damaged?", "options": [{"label": "A", "text": "Flexor Hallucis Longus", "correct": false}, {"label": "B", "text": "Peroneus brevis", "correct": false}, {"label": "C", "text": "Peroneus longus", "correct": true}, {"label": "D", "text": "Tibialis anterior", "correct": false}], "correct_answer": "C. Peroneus longus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Peroneus longus The tendon of the peroneus longus muscle occupies the groove on the lower surface of the cuboid bone.</p>\n<p><strong>Highyeild:</strong></p><p>Peroneus longus muscle tendon grooves under the Cuboid bone</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Flexor Hallucis Longus The flexor hallucis longus tendon occupies a groove on the posterior surface of the body of the talus and a groove on the inferior surface of the calcaneus during its course. Option B. Peroneus brevis Peroneus brevis tendon then runs forward along the lateral side of the calcaneus, above the calcaneal tubercle and the tendon of the fibularis longus. It inserts into the tuberosity at the base of the fifth metatarsal on its lateral side. Option D. Tibialis posterior The tibialis posterior muscle tendon occupies the medial malleolar groove of the tibia.</p>\n<p><strong>Extraedge:</strong></p><p>The fibular collateral ligament is a degenerated part of the Peroneus Longus muscle. The tibial collateral ligament represents the degenerated part of the adductor magnus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An 8-year-old boy was admitted to the emergency department complaining of nausea, vomiting, fever, and loss of appetite. On examination, he was found to have tenderness and pain in the right lower quadrant. Based on signs and symptoms, the diagnosis of acute appendicitis was made. During an appendectomy performed at McBurney's point, which structures are most likely to be injured?", "options": [{"label": "A", "text": "Deep circumflex femoral artery", "correct": false}, {"label": "B", "text": "Inferior epigastric artery", "correct": false}, {"label": "C", "text": "Illio- hypogastric nerve", "correct": true}, {"label": "D", "text": "Genitofemoral nerve", "correct": false}], "correct_answer": "C. Illio- hypogastric nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Illio- hypogastric nerve The illio-hypogastric nerve runs medially and inferiorly between the internal oblique and transverse abdominal near McBurney’s point, at the junction of the lateral one-third of a line between the anterior superior iliac spine and the umbilicus.</p>\n<p><strong>Highyeild:</strong></p><p>Iliohypogastric nerve location near McBurney’s point</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Deep circumflex femoral artery Option B. Inferior epigastric artery Option D. Genitofemoral nerve Other structures mentioned in Option A, B and D are not found near McBurney’s point.</p>\n<p><strong>Extraedge:</strong></p><p>The genitofemoral nerve arises from the lumbar plexus. It supplies sensation to the skin of the anterior scrotal area in males, mons pubis in females, and the upper segment of the anterior thigh in both males and females.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient presents with sensory loss on the adjacent sides of the great and second toes and impaired dorsiflexion of the foot. Which nerve innervates this area?", "options": [{"label": "A", "text": "Superficial Peroneal", "correct": false}, {"label": "B", "text": "Tibial nerve", "correct": false}, {"label": "C", "text": "Deep peroneal", "correct": true}, {"label": "D", "text": "Sural", "correct": false}], "correct_answer": "C. Deep peroneal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deep peroneal The deep peroneal nerve supplies the anterior muscles of the leg, including the tibialis anterior, extensor hallucis longus, extensor digitorum longus, and peroneus tertius muscles, which dorsiflex the foot . The medial branch of the deep peroneal nerve supplies the skin of adjacent sides of the great and second toes. The lateral branch supplies the extensor digitorum brevis and extensor hallucis brevis.</p>\n<p><strong>Highyeild:</strong></p><p>Deep Peroneal Nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Superficial Peroneal The superficial peroneal nerve innervates the peroneus longus and brevis, which plantar flexes the foot and supplies the skin on the side of the lower leg and the dorsum of the ankle and foot. Option B. Tibial nerve The tibial nerve innervates the muscles of the posterior compartment which are the plantar aspect of the foot. Option D. Sural The sural nerve supplies the skin on the posterolateral aspect of the leg and the lateral aspect of the foot and little toe.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The marked dermatome is:", "options": [{"label": "A", "text": "L4", "correct": false}, {"label": "B", "text": "L5", "correct": false}, {"label": "C", "text": "S1", "correct": false}, {"label": "D", "text": "S2", "correct": true}], "correct_answer": "D. S2", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682081098-QTDA044013IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>S2 The dermatome supply of the marked area is S2.</p>\n<p><strong>Highyeild:</strong></p><p>Dermatome of Lower limb</p>\n<p><strong>Extraedge:</strong></p><p>Dermatome of Lower limb along with the name of nerves</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Cutaneous innervations of the dorsum of the foot are marked in the given Image. Area D is supplied by:", "options": [{"label": "A", "text": "Deep Peroneal Nerve", "correct": false}, {"label": "B", "text": "Superficial peroneal nerve", "correct": true}, {"label": "C", "text": "Tibial nerve", "correct": false}, {"label": "D", "text": "Sciatic nerve", "correct": false}], "correct_answer": "B. Superficial peroneal nerve", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682081121-QTDA044014IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superficial peroneal nerve Common peroneal nerves wind around the neck of the fibula and divide into superficial and deep peroneal nerves. The superficial peroneal nerve innervates the peroneus longus and brevis, which plantar flexes the foot and supplies the skin on the side of the lower leg and the dorsum of the ankle and foot. D area is supplied by the superficial peroneal nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Cutaneous innervation of Foot</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Deep Peroneal Nerve Deep peroneal nerve- supplies the extensor compartment of the leg . B area is supplied by deep peroneal nerve Option C. Tibial nerve The tibial nerve originates from the L4-S3 spinal nerve roots and provides motor and sensory innervation to most of the posterior leg and foot . The sural nerve supplies the C area. Option D. Sciatic nerve The sciatic nerve has no direct cutaneous functions. It does provide indirect sensory innervation via its terminal branches . An area is supplied by the saphenous nerve</p>\n<p><strong>Extraedge:</strong></p><p>In the posterior leg, the sural nerve courses alongside the small saphenous vein. The sural nerve is purely sensory. Its main function is to provide the sensory supply for the posterolateral aspect of the distal third of the lateral leg aspect of the foot, heel and ankle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are branches of the lumbar plexus except:", "options": [{"label": "A", "text": "Iliohypogastric Nerve", "correct": false}, {"label": "B", "text": "Ilioinguinal nerve", "correct": false}, {"label": "C", "text": "Obturator nerve", "correct": false}, {"label": "D", "text": "Subcostal nerve", "correct": true}], "correct_answer": "D. Subcostal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Subcostal nerve Subcostal nerve is the anterior division of the 12th thoracic nerve, and is larger than the other intercostal nerves . The subcostal nerve provides motor supply to the rectus abdominis, intercostal, and anterior abdominal wall muscles . The nerve communicates with the iliohypogastric nerve and gives a motor branch to the pyramidalis.</p>\n<p><strong>Highyeild:</strong></p><p>Branches of Lumbar Plexus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A, B and C are branches of lumbar plexus</p>\n<p><strong>Extraedge:</strong></p><p>The sacral plexus is a nerve plexus that provides motor and sensory nerves for the posterior thigh, most of the lower leg and foot, and part of the pelvis. It is part of the lumbosacral plexus and emerges from the lumbar and sacral vertebrae (L4-S4).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following associations of the lower limb, movements and root values is incorrect?", "options": [{"label": "A", "text": "Hip flexion L3, L4", "correct": true}, {"label": "B", "text": "Knee flexion L5, S1", "correct": false}, {"label": "C", "text": "Ankle dorsiflexion L4, L5", "correct": false}, {"label": "D", "text": "Inversion: L4", "correct": false}], "correct_answer": "A. Hip flexion L3, L4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Hip flexion L3, L4 Hip flexion is achieved mainly by iliopsoas which L2 and L3 segmentally innervate.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Knee flexion L5, S1 Knee flexion is primarily facilitated by the action of the hamstring muscles, which are segmentally innervated by L5 and S1 ( Sciatic nerve). Option C. Ankle dorsiflexion L4, L5 Ankle dorsiflexion is achieved by the action of the muscles of the anterior compartment of the leg, corresponding to segmental innervation from levels L1 and L5 (deep peroneal nerve). Option D. Inversion: L4 Inversion is principally due to the tibialis posterior (tibial nerve) action. This corresponds to segmental innervation by the L4 root.</p>\n<p><strong>Extraedge:</strong></p><p>Ankle plantarflexion, achieved by the action of the muscles of the posterior compartment to segmental innervation from levels of S1 and S2 Knee extension is accompanied by quadriceps, which L4 and L4 segmentally innervate Hip extension has the root value of L4 and L5.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following may occur in common peroneal nerve injury?", "options": [{"label": "A", "text": "Loss of plantar flexion", "correct": false}, {"label": "B", "text": "Foot drop", "correct": true}, {"label": "C", "text": "Loss of sensation over sole", "correct": false}, {"label": "D", "text": "Innervation of the foot affected", "correct": false}], "correct_answer": "B. Foot drop", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Foot drop Common peroneal nerve is the commonest nerve to be paralysed. Can be injured due to fracture neck of fibula, lathi injury on the lateral side of the knee joint, due to plaster on leg</p>\n<p><strong>Highyeild:</strong></p><p>Effect of injury: Motor loss, i.e. Foot drop( loss of dorsiflexion or extension) Sensory loss at the back and lateral side of the leg, most dorsum of the foot. Paralysis of anterior compartment muscles of leg loss of foot eversion</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Loss of plantar flexion Loss of plantar flexion of the foot occurs due to injury of the tibial nerve. Option C. Loss of sensation over sole Sole is supplied by the branches (medial and lateral plantar nerve) of the tibial nerve. Option D. Innervation of the foot affected Innervation of the foot is not directly done by the common peroneal nerve.</p>\n<p><strong>Extraedge:</strong></p><p>Innervation of the foot is done by following seven nerves, as shown in the image below. Innervation of foot</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Most commonly damaged nerve in the lower limb:", "options": [{"label": "A", "text": "Femoral", "correct": false}, {"label": "B", "text": "Sciatic", "correct": false}, {"label": "C", "text": "Common peroneal", "correct": true}, {"label": "D", "text": "Tibial", "correct": false}], "correct_answer": "C. Common peroneal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Common peroneal Common peroneal nerve is more superficial and lateral to the neck of the fibula in the lower limb, hence more susceptible to injury. Injury manifestation: Compromise of the superficial peroneal nerve and Deep peroneal nerve. Sensory symptoms: loss of sensation on the territory of the common peroneal nerve and superficial peroneal nerve, which supplies most of the lateral aspect of the leg and dorsum of the foot. Motor symptoms: foot drop and loss of foot eversion.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options: A, B & D. Femoral, Sciatic and Tibial nerves are not commonly injured as the common peroneal nerve.</p>\n<p><strong>Extraedge:</strong></p><p>Footdrop is an inability to dorsiflex the foot . Patients with foot drop have a characteristic \"steppage\" gait . As the patient walks, the knee of the affected limb is elevated to an abnormal height during the swing phase to prevent the foot from dragging. At the end of the swing phase, the foot \"slaps'' the ground. Also, the unaffected limb often acquires a characteristic tiptoe pattern of gait during the stance phase. A typical cause of foot drop is damage to the common fibular nerve. Other causes include disc protrusion compressing the LS nerve root, disorders of the sciatic nerve and the lumbosacral plexus, and spinal cord and brain pathologies.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The posterior cutaneous nerve of the thigh supplies skin overlying all EXCEPT:", "options": [{"label": "A", "text": "Lateral aspect of thigh", "correct": true}, {"label": "B", "text": "Posterior inferior aspect of buttock", "correct": false}, {"label": "C", "text": "Scrotum", "correct": false}, {"label": "D", "text": "Popliteal Fossa", "correct": false}], "correct_answer": "A. Lateral aspect of thigh", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral aspect of thigh Posterior Cutaneous Nerve of the thigh does not supply the lateral aspect of the thigh. Lateral thigh is supplied by the lateral femoral cutaneous nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Lateral cutaneous nerve area of distribution</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B, C & D. All of the above regions are innervated by the posterior cutaneous nerve of the thigh. Posterior Cutaneous nerve of thigh supplies. Gluteal region, the perineum, and the back of the thigh( and leg) region primarily. It also covers the cutaneous region on the posterior inferior aspect of the buttock region and scrotum/ labia majora</p>\n<p><strong>Extraedge:</strong></p><p>Cutaneous innervation of lower limb</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The Trendelenburg test is positive on the right side. Nerve injured is:", "options": [{"label": "A", "text": "Right Inferior Gluteal", "correct": false}, {"label": "B", "text": "Right femoral", "correct": false}, {"label": "C", "text": "Right Superior gluteal", "correct": false}, {"label": "D", "text": "Left Superior gluteal", "correct": true}], "correct_answer": "D. Left Superior gluteal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left Superior gluteal Superior gluteal nerve , if injured, paralyses the 3 muscles, gluteus medius, gluteus minimus and tensor fascia latae and hence leads to Trendelenburg test positive , which is evident on the contralateral side. Pelvis sags on the unsupported lower limb.</p>\n<p><strong>Highyeild:</strong></p><p>In the Trendelenburg sign, the action of gluteus medius (superior pelvic tilt of contralateral hip) is absent and we observe that there is a downward drop of the unsupported hip- due to unopposed action of gravity. This leads to a lurching gait in the patient. Trendelenburg Sign</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Right Inferior Gluteal Inferior gluteal nerve innervates Gluteus maximus muscle and not gluteus medius or minimus muscles . Option B. Right femoral Femoral nerve innervates muscles of the anterior compartment of the thigh (Sartorius, Quadriceps femoris). Option C. Right Superior gluteal Injury to the right superior gluteal nerve would result in sagging of the left side of the pelvis when the affected individual stands on the right limb.</p>\n<p><strong>Extraedge:</strong></p><p>Trendelenburg's sign is found in people with weak or paralyzed abductor muscles of the hip, namely gluteus medius and gluteus minimus . It is named after the German surgeon Friedrich Trendelenburg. It is often incorrectly referenced as the Trendelenburg test, which is a test for vascular insufficiency in the lower extremities.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "After removing cancerous lymph nodes from the lateral pelvic wall, a patient develops painful spasms of the adductor muscles and sensory deficits in the medial thigh region. The adductor muscles are innervated by which of the following nerves?", "options": [{"label": "A", "text": "Femoral", "correct": false}, {"label": "B", "text": "Inferior gluteal", "correct": false}, {"label": "C", "text": "Obturator", "correct": true}, {"label": "D", "text": "Pudendal", "correct": false}], "correct_answer": "C. Obturator", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Obturator The obturator nerve innervates the adductor group of muscles and provides cutaneous innervation on the medial region of the thigh. The nerve originates from the lumbar plexus, runs on the lateral aspect of the pelvic wall, and exits through the obturator canal to reach the medial aspect of the thigh. Lying on the lateral pelvic wall, it may be injured by surgical mishaps.</p>\n<p><strong>Highyeild:</strong></p><p>Obturator Nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The femoral nerve innervates the anterior aspect of the thigh, and the muscles are sartorius and the quadriceps femoris. Option: B. The inferior gluteal nerve innervates the gluteus maximus muscle and is confined to the gluteal region. Option: D. The pudendal nerve is sensory to the genitalia, motor to the perineal muscles, the external urethral sphincter, and the external anal sphincter .</p>\n<p><strong>Extraedge:</strong></p><p>Cutaneous innervation area of the obturator nerve</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 63-year-old woman visited the OPD orthopedic clinic with complaints of pain in her foot for more than a year. Radiographic and physical examinations give evidence of constant extension at the metatarsophalangeal joints, hyperflexion at the proximal interphalangeal joints, and extension of distal interphalangeal joints (Image). Which of the following terms is most accurate to describe the signs of physical examination?", "options": [{"label": "A", "text": "Pes Planus", "correct": false}, {"label": "B", "text": "Pes cavus", "correct": false}, {"label": "C", "text": "Hammer toes", "correct": true}, {"label": "D", "text": "Claw toes", "correct": false}], "correct_answer": "C. Hammer toes", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682081190-QTDA044022IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Hammer toes The patient’s complaint is due to her case of hammer toes. Hammer toe can affect any toe but most commonly the second toe, then the third or fourth toes. It results most commonly from wearing shoes that are too short or shoes with heels that are too high. Rheumatoid arthritis is also a common cause</p>\n<p><strong>Highyeild:</strong></p><p>In the hammer toe, the metatarsophalangeal joint is extended, the proximal interphalangeal joint is flexed, and the distal phalanx points downward, looking like a hammer. Hammer toe can occur as a result of a bunion.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Pes Planus Pes planus commonly referred to as “flat feet,” is a relatively common foot deformity and is defined by the loss of the medial longitudinal arch of the foot where it contacts or nearly contacts the ground. Option B. Pes cavus Pes cavus is the opposite of flat foot —the patient has a high, flexed plantar arch ; it occurs as a result of hereditary motor and sensory neural problems. It is painful because of metatarsal compression. Option D. Claw toes In claw toes, both the proximal and distal interphalangeal joints are strongly flexed; this results in muscle imbalance of the foot.</p>\n<p><strong>Extraedge:</strong></p><p>Hallux Valgus is considered one of the most common foot deformities and is described as “lateral deviation of the hallux and its consequent distancing from the median axis of the body”.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A urologist doctor is teaching her resident to perform a vasectomy. She explains that he has to inject the anaesthetic into the skin of the scrotum in preparation for the incision of its lateral aspect. This surgical location allows for easy access to the spermatic cord. Which of the following nerves innervates the skin of the scrotum?", "options": [{"label": "A", "text": "Femoral Nerve", "correct": false}, {"label": "B", "text": "Iliohypogastric nerve", "correct": false}, {"label": "C", "text": "Ilioinguinal nerve", "correct": true}, {"label": "D", "text": "Obturator nerve", "correct": false}], "correct_answer": "C. Ilioinguinal nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ilioinguinal nerve The anterior aspect of the scrotum is innervated by branches of the ilioinguinal nerve (L1). Other nerves innervating the scrotum are branches of the genitofemoral nerve (L1, L2), pudendal nerve (S2-S4), and posterior femoral cutaneous nerve (S2, S3).</p>\n<p><strong>Highyeild:</strong></p><p>Ilioinguinal nerve is a branch of the first lumbar nerve (L1). It separates from the first lumbar nerve along with the larger iliohypogastric nerve. It emerges from the lateral border of the psoas major just inferior to the iliohypogastric, and passes obliquely across the quadratus lumborum and iliacus. Ilioinguinal nerve then perforates the transversus abdominis near the anterior part of the iliac crest and communicates with the iliohypogastric nerve between the transversus and the internal oblique muscle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Femoral Nerve The femoral nerve (L2-L4, choice A) supplies sensory innervation to the anteromedial thigh, hip, and knee joint. It also innervates muscles of the anterior compartment of the thigh. Option B. Iliohypogastric nerve The iliohypogastric nerve (L1, choice B) provides sensory innervation over the iliac crest and the hypogastric region. Option D. Obturator nerve The obturator nerve (L2-L4, choice D) s upplies motor innervation to the medial compartment of the thigh. The subcostal nerve provides motor innervation for the lower part of the external oblique muscle and sensory innervation over the hip and anterior superior iliac spine.</p>\n<p><strong>Extraedge:</strong></p><p>The subcostal nerve provides motor supply to the rectus abdominis, intercostal, and anterior abdominal wall muscles. The nerve communicates with the iliohypogastric nerve and gives a motor branch to the pyramidalis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An athlete comes to the physician with inflammation on the lateral side of the right thigh. He presents with hip flexion, abduction, and external rotation, along with subluxation of the tibia, flexion, and lateral knee rotation. Ober’s test is positive. What is the possible diagnosis?", "options": [{"label": "A", "text": "Hypertrophy of the quadriceps femoris", "correct": false}, {"label": "B", "text": "Iliotibial band contracture", "correct": true}, {"label": "C", "text": "Biceps femoris tendinopathy", "correct": false}, {"label": "D", "text": "Lateral collateral ligament sprain", "correct": false}], "correct_answer": "B. Iliotibial band contracture", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Iliotibial band contracture The clinical vignette comes to a diagnosis of Iliotibial band contracture . It is the tightening and inflammation of the iliotibial tract. This is a modification of the deep fascia of the lower limb (fascia lata).</p>\n<p><strong>Highyeild:</strong></p><p>Iliotibial tract contracture is the tightening and inflammation of the iliotibial tract . It causes the above symptoms. This tract is attached to the hip capsule, tubercle of the iliac crest, and Girdy’s tubercle of the tibia. It gives attachment to the tensor fascia lata and the gluteus maximus muscles. Subluxation of the tibia is seen by its attachment. Another feature of this disorder is genu valgus wherein the knees touch each other while standing. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The quadriceps muscles are involved in the external rotation of the hip . Hypertrophy of these muscles doesn’t cause subluxation of the tibia and lateral rotation of the knee. Hence, it is the wrong answer Option: C. Biceps femoris is the flexor of the leg and is a part of the hamstring group of muscles. Biceps femoris tendinopathy/ tendonitis is inflammation of the biceps femoris tendon that is behind the knee. Its clinical manifestations are limited to the knee joint (inability to flex and extend). Hence, it is the wrong answer. Option: D. Lateral collateral ligament is a ligament of the knee joint. A lateral collateral ligament sprain is the tear of this ligament due to undue force. The clinical features of this disorder are limited to the knee joint. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>The iliotibial band tract or IT band (ITB) is a longitudinal fibrous sheath that runs along the lateral thigh and serves as an important structure involved in lower extremity motion. The ITB is also sometimes known as Maissiat's band.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An obese pregnant woman complains of numbness and tingling sensation in the outer right thigh during her monthly OBG visit. She indicates that the abnormal sensation aggravated following her second trimester of pregnancy. Laboratory investigations show no signs of neoplasm. There are no other comorbidities. What is the probable diagnosis?", "options": [{"label": "A", "text": "Bernhardt-Roth Syndrome", "correct": true}, {"label": "B", "text": "Creutzfeldt-Jakob disease", "correct": false}, {"label": "C", "text": "Peutz-Jeghers syndrome", "correct": false}, {"label": "D", "text": "Eagle-Barrett syndrome", "correct": false}], "correct_answer": "A. Bernhardt-Roth Syndrome", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Bernhardt-Roth Syndrome The clinical vignette comes to a diagnosis of Bernhardt-Roth syndrome . It is also known as meralgia paresthetica. It is due to the entanglement/ entrapment of the lateral cutaneous nerve of the thigh.</p>\n<p><strong>Highyeild:</strong></p><p>Bernhardt-Roth syndrome is also known as meralgia paresthetica. It is congenitally seen when the lateral cutaneous nerve of the thigh forms in between the fibres of the inguinal ligament (entrapment) . It is caused after birth due to obesity, pregnancy, wearing tight clothing, and cancers. The symptoms include numbness and tingling sensation over the lateral/ outer part of the thigh. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Creutzfeldt-Jakob disease (CJD) is a rapidly progressive, fatal neurodegenerative disorder. It is believed to be caused by an abnormal isoform of a cellular glycoprotein known as the prion protein, it doesn’t present with the above-stated signs and symptoms. Hence, it is the wrong answer. Option: C. Peutz-Jeghers syndrome is an autosomal dominant genetic disorder characterised by the formation of benign polyps in the GI tract. The symptoms and signs include brownish spots on the lips, gums, oral mucosa, and skin, clubbing of fingers or toes, abdominal cramping, dark freckles around the lips, blood in the stool, and vomiting. Hence, it is the wrong answer Option: D. Eagle-Barrett syndrome is also known as prune-Belly syndrome. It is a rare disorder characterised by the partial or complete absence of the abdominal muscles. It is also associated with the failure of the descent of both testes into the scrotum, along with urinary tract malformations. The other symptoms and signs include urachus, Harrison's groove, and pectus carinatum. Hence, it is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A farmer consults a physician with complaints of a stiff hip and intense pain in the groin and gluteal region that aggravates after intense exercise/ movement. Physical examination shows inflammation of the posterior and lateral sides of the thigh. There are also minor and gradually enlarged swellings in the abdomen and upper limb after inspection 2 days later. A blood test was taken after the patient showed signs of blood poisoning. The blood was found to have Staphylococcus aureus bacteria. There is no sign of gangrene. What is the probable diagnosis?", "options": [{"label": "A", "text": "Leptospirosis", "correct": false}, {"label": "B", "text": "Necrotizing fasciitis", "correct": false}, {"label": "C", "text": "Pyomyositis", "correct": true}, {"label": "D", "text": "Clostridial myonecrosis", "correct": false}], "correct_answer": "C. Pyomyositis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pyomyositis The clinical vignette comes to the diagnosis of pyomyositis. It is a rare bacterial infection of the skeletal muscle. It is caused by many fungi, viruses, and bacteria but predominantly by the Staphylococcus aureus bacteria . The signs and symptoms include pain and tenderness of the affected muscle, fever, and abscess formation.</p>\n<p><strong>Highyeild:</strong></p><p>Pyomyositis is a rare bacterial infection of the skeletal muscle. It is caused by the Staphylococcus aureus The signs and symptoms include pain and tenderness of the affected muscle, fever, and abscess formation . The muscle involved here is the tensor fascia lata. Hence, it is often accompanied by arthritis of the hip joint (this muscle is attached to the iliotibial tract attached to the hip capsule). The bacteria can travel through the bloodstream and can affect other skeletal muscles of the body. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Leptospirosis is a blood infection. It is caused by the bacteria Leptospira. The signs and symptoms include headaches, hemothorax, hematemesis, and meningitis. It doesn’t result in any hip joint-related manifestations. Hence, it is the wrong answer. Option: B. Necrotizing fasciitis (NF) is a flesh-eating disease. It is an infection that results in necrosis of connective tissue and fascia. It is a severe disease of sudden onset, and it spreads rapidly. The symptoms usually include red or purple skin in the affected area, tenderness, and vomiting. It is caused by the group A streptococcus bacteria. Hence, it is the wrong answer. Option: D. Clostridial myonecrosis is a bacterial infection that produces tissue gas accompanied by gangrene. The Clostridium perfringens bacteria cause it . This disorder doesn’t result in any hip joint-related manifestations. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Treatment of pyomyositis abscess has traditionally been with incision and drainage or guided aspiration followed by a prolonged course of antibiotics.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 70-year-old female comes to the physician as a part of the monthly therapy session following a cardiac catheterization and angioplasty through the right femoral artery one month before. She complains of numbness in her right lower extremities and pain in the groin and anterior right thigh examination shows normal adduction of the thigh and dorsiflexion of the ankle. The right knee jerk is absent and is accompanied by a loss of sensation of pain, touch, and temperature over the anterior part of the thigh. Which of the following nerves are involved in this case?", "options": [{"label": "A", "text": "Fascia Lata", "correct": true}, {"label": "B", "text": "Fascia camper", "correct": false}, {"label": "C", "text": "Cribriform fascia", "correct": false}, {"label": "D", "text": "Colles fascia", "correct": false}], "correct_answer": "A. Fascia Lata", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fascia Lata Fascia lata is the deep fascia of the thigh. It has many modifications, such as the thigh compartments and the iliotibial tract. It is tough and membranous and is ideally used for this procedure . Hence, it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>The fascia lata is attached, above and behind (i.e. proximal and posterior), to the back of the sacrum and coccyx; laterally, to the iliac crest; in front, to the inguinal ligament, and to the superior ramus of the pubis; and medially, to the inferior ramus of the pubis, to the inferior ramus and tuberosity of the ischium, and to the lower border of the sacrotuberous ligament.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Fascia Camper is the superficial fatty layer of the abdominal wall . Since rhinoplasty surgery requires tough and membranous connective tissue, unlike fascia Camper, it is the wrong answer. Option: C. Cribriform fascia is a modification of the fascia lata. It covers the saphenous opening into which the great saphenous vein drains. It is perforated in nature and is not used for this procedure. Hence, it is the wrong answer. Option: D. Colle’s fascia is the membranous fascia of the perineum. It is the continuation of the Dartos fascia and fascia Scarpa. It is essential for the support and functioning of the perineal organs. Hence, it is not used in the procedure primarily. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>The fascia lata surrounds the tensor fasciae latae muscle. It is a fibrous sheath that encircles the thigh subcutaneously. This encircling of the muscle allows the muscles to be bound together tightly</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 25-year-old male comes to the physician complaining of slight paralysis and pain in his right leg. Physical examination shows pallor of the anterior part of the right thigh. There is paraesthesia and pulselessness of the main arteries of the leg. What is the most probable diagnosis?", "options": [{"label": "A", "text": "Pyomyositis", "correct": false}, {"label": "B", "text": "Bernhardt-Roth syndrome", "correct": false}, {"label": "C", "text": "Iliotibial contracture", "correct": false}, {"label": "D", "text": "Compartment syndrome", "correct": true}], "correct_answer": "D. Compartment syndrome", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Compartment syndrome Compartment syndrome is a severe condition caused by the compression of the contents of the compartments of the thigh due to accumulation of blood or non-elasticity of the fascia lata. The thigh has three compartments that are divided by the modification of the fascia lata.</p>\n<p><strong>Highyeild:</strong></p><p>Compartment syndrome is caused by the compression of the contents of the compartments of the thigh due to accumulation of blood or non-elasticity of the fascia lata. The thigh has three compartments divided by the modification of the fascia lata. The compartment involved in this case is the anterior compartment. The symptoms are the 5 P's: pallor, pain, paraesthesia, pulselessness, and paralysis. Paralysis is due to compression of the femoral nerve and its branches. Paleness and pulselessness are due to compression of the femoral artery and its branches, loss or difficulty of movement is due to compression and wasting of the muscles.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Pyomyositis is a rare bacterial infection of the skeletal muscle. It is caused by the Staphylococcus aureus The signs and symptoms include pain and tenderness of the affected muscle, fever, and abscess formation. The muscle involved here is the tensor fascia lata. Hence, it is often accompanied by arthritis of the hip joint (this muscle is attached to the iliotibial tract attached to the hip capsule). The bacteria can travel through the bloodstream and can affect other skeletal muscles of the body. Hence, it is the wrong answer. Option: B. Bernhardt-Roth syndrome is also known as meralgia paresthetica. It is congenitally seen when the lateral cutaneous nerve of the thigh forms in between the fibres of the inguinal ligament (entrapment). It is caused after birth due to obesity, pregnancy, wearing tight clothing, and cancers. The symptoms include numbness and tingling sensation over the lateral/ outer part of the thigh. Hence, it is the wrong answer. Option: C. Iliotibial tract contracture is the tightening and inflammation of the iliotibial tract. It causes the above symptoms. This tract is attached to the hip capsule, tubercle of the iliac crest, and Girdy’s tubercle of the tibia. It gives attachment to the tensor fascia lata and the gluteus maximus muscles. Subluxation of the tibia is seen by its attachment. Another feature of this disorder is genu valgus, wherein the knees touch each other while standing. Hence, it is the correct answer.</p>\n<p><strong>Extraedge:</strong></p><p>A surgical procedure called fasciotomy is the most effective chronic exertional compartment syndrome treatment. It involves cutting open the inflexible tissue encasing each affected muscle compartment. This relieves the pressure.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 70-year person is rushed to the ER following a fatal blow to his spine after a fall down the stairs. The herniation of the nucleus pulposus is seen at the level of the bifurcation of the abdominal aorta. Which of the following is true in this case?", "options": [{"label": "A", "text": "The patient will have a loss of sensation over the upper medial part of thigh", "correct": false}, {"label": "B", "text": "The patient will have a loss of sensation over his pubic region", "correct": false}, {"label": "C", "text": "The patient will have a loss of sensation over the dorsum of foot", "correct": true}, {"label": "D", "text": "The patient will have a loss of sensation over his upper lateral part of thigh", "correct": false}], "correct_answer": "C. The patient will have a loss of sensation over the dorsum of foot", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The patient will have a loss of sensation over the dorsum of foot The patient has herniated his spinal disc at the level of the L4 vertebral level as indicated by the iliac crest and bifurcation of the abdominal aorta into the right and left common iliac arteries. The nerve from this level contributes to forming the femoral nerve, obturator nerve, and lumbosacral trunk. Option: C. The nerve is responsible for the cutaneous innervation of the dorsum of foot is majority from the superficial and deep peroneal nerve. Both these nerves are branches of the common peroneal nerve. CPN is a smaller terminal branch of the Sciatic nerve that arises from the sacral plexus contributed by the lumbosacral trunk. Hence, it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Cutaneous innervation of lower limb</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The nerve responsible for the cutaneous innervation of the upper medial part of the thigh is the femoral branch of the genitofemoral nerve. This nerve originates from the L2 level. Hence, it is the wrong answer. Option: B. The nerve responsible for the cutaneous innervation of the pubic region is the ilioinguinal nerve . This nerve originates from the L1 level. Hence, it is the wrong answer. Option: D. The nerve responsible for the cutaneous innervation of the upper lateral part of the thigh is the lateral cutaneous nerve of the thigh. This nerve originates from the L2 and L3 levels. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>The saphenous nerve runs posterior to the greater saphenous vein in the leg and divides into an anterior and posterior branch approximately 3 cm proximal to the tip of the medial malleolus. These branches terminate in the integument proximal to the tip of the medial malleolus, while the vein continues into the foot.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A gymnast is unable to tense his linea alba. His healthcare professional tells him that the tensor of the linea alba is a small muscle in the lower abdomen. He also says that muscle has lost its innervation. Which nerve is responsible for innervating that muscle?", "options": [{"label": "A", "text": "Subcostal nerve and ilioinguinal nerve", "correct": false}, {"label": "B", "text": "Subcostal nerve", "correct": false}, {"label": "C", "text": "Genitofemoral nerve", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above The patient has lost the function of his pyramidalis muscle. It is a small triangular-shaped muscle between the anterior surface of the rectus abdominis and the posterior surface of the rectus sheath. One of its functions is to tense the linea alba . The subcostal nerve is the 12th intercostal nerve. Pyramidalis can be innervated via the ventral rami of the twelfth thoracic, first lumbar or second lumbar spinal nerves : fibres travel in anterior cutaneous branches of the subcostal nerve, the ilioinguinal nerve or the genital branch of the genitofemoral nerve. The linea alba is a tendinous band extending from the xiphoid process to the pubic symphysis. The pyramidal muscle is paired and helps to tense the linea alba. Hence, it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>The pyramidalis muscle is part of the anterior abdominal wall. Inferiorly, the pyramidalis muscle attaches to the pelvis in two places: the pubic symphysis and pubic crest, arising by tendinous fibres from the anterior part of the pubis and the anterior pubic ligament. Superiorly, the fleshy portion of the pyramidalis muscle passes upward, diminishing in size as it ascends, and ends by a pointed extremity that is inserted into the linea alba, midway between the umbilicus and pubis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A, B & C. All innervate the pyramidalis muscle.</p>\n<p><strong>Extraedge:</strong></p><p>The pyramidalis muscle is present in 80% of the human population. It may be absent on one or both sides; the lower end of the rectus then becomes proportionately increased in size.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following muscles has dual nerve supply?", "options": [{"label": "A", "text": "Adductor Magnus", "correct": true}, {"label": "B", "text": "Adductor longus", "correct": false}, {"label": "C", "text": "Sartorius", "correct": false}, {"label": "D", "text": "Vastus lateralis", "correct": false}], "correct_answer": "A. Adductor Magnus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Adductor Magnus Adductor Magnus is the largest muscle of the medial compartment of the thigh, and also its ischial head is part of the hamstring muscle group. The adductor magnus is innervated by both the obturator and tibial part of the sciatic nerve . Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Adductor longus Adductor longus is a muscle of the medial compartment of the thigh and is supplied only by the obturator nerve Option: C. Sartorius Sartorius is a muscle of the anterior compartment of the thigh and is supplied only by the femoral nerve. Hence, it is the wrong answer. Option D. Vastus lateralis Vastus lateralis is a muscle of the anterior compartment of the thigh and is supplied only by the femoral nerve . Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>The pectineus is considered a transitional muscle between the anterior thigh and medial thigh; this is due to innervation mainly from the femoral nerve and also sometimes from the obturator nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A nerve contributes to the formation of both the lumbosacral trunk and the nerves of the anterior and medial muscular compartments of the thigh. From the radiological image below, which arrow indicates this nerve?", "options": [{"label": "A", "text": "1st Arrow", "correct": false}, {"label": "B", "text": "3rd arrow", "correct": false}, {"label": "C", "text": "4th arrow", "correct": true}, {"label": "D", "text": "5th arrow", "correct": false}], "correct_answer": "C. 4th arrow", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682081222-QTDA044032IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4th arrow The 4th lumbar nerve is also known as the Nervus furcalis as it contributes to forming the obturator and femoral nerves along with the lumbosacral trunk.</p>\n<p><strong>Highyeild:</strong></p><p>Nervus furcalis The furcal nerve (forked nerve) links the lumbar plexus and the sacral plexus . Its dorsal and ventral branches have fibers that branch out to become part of the femoral and obturator nerves. The furcal nerve is found in the lumbosacral trunk, most commonly at the level of the fourth lumbar vertebra (L4). The 4th arrow indicates the fourth lumbar nerve that gives rise to the roots of the obturator and femoral nerves and contributes to the formation of the lumbosacral trunk. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The 1st arrow indicates the first lumbar nerve that gives rise to the ilioinguinal and iliohypogastric nerves. Hence, it is the wrong answer. Option: B. The 3rd arrow indicates the third lumbar nerve that gives rise to the roots of the obturator and femoral nerves. Hence, it is the wrong answer. Option: D. The 5th arrow indicates the fifth lumbar nerve that gives rise to the lumbosacral trunk alone. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>The furcal nerve is found at various locations and can give problems in the diagnosis of radiculopathy or sciatic pain. It is the main cause of atypical symptoms of sciatic and radicular pain, often due to lumbar disc herniation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A person in the ER is in a hypovolemic shock. His peripheral venous system is unclear/ inaccessible due to unknown reasons. Hence, a venous cutdown (Image) is done through the vein that is responsible for draining the dorsum of the foot, shin, and thigh and is accompanied by a branch of the posterior division of the femoral nerve. The vein can be accessed at which of the following sites?", "options": [{"label": "A", "text": "Anterior to the medial epicondyle", "correct": false}, {"label": "B", "text": "Anterior to the medial malleolus", "correct": true}, {"label": "C", "text": "Through the saphenous opening", "correct": false}, {"label": "D", "text": "Tributaries to the posterior tibial vein", "correct": false}], "correct_answer": "B. Anterior to the medial malleolus", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682081225-QTDA044033IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior to the medial malleolus The vein of choice for venous cutdown in cases where peripheral cannulation is not possible is the saphenous vein (great saphenous vein ). The saphenous vein in front of the medial malleolus is easily accessible as it is more superficial along its course. It is accompanied by the saphenous nerve (branch of the posterior division of the femoral nerve . Hence, it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>The saphenous nerve is commonly known to contribute to the sensory innervation of the lower extremity. Saphenous nerve provides sensory innervation of the medial leg and calf, terminating distally at the “ball” of the great toe.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The saphenous vein changes its course from the knee joint's posterior surface to the knee joint's anterior surface after reaching the medial epicondyle. It is also hard to access this location. Hence, it is the wrong answer. Option: C. The saphenous vein drains into the femoral vein through the saphenous opening (modification of the fascia lata). Cannulation is easy at this site, but it is hard to access as it is deep. There are chances of damaging essential structures such as those of the femoral triangle, etc. hence, it is the wrong answer. (it can be used in cases where the vein in the front medial malleolus is inaccessible due to damage/ infection of the foot) Option: D. The tributaries of the posterior tibial vein are small and can’t be used for cannulation. Further, it is in close contact with the respective artery. It is a deep structure. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Cutaneous distribution of nerve on the anterior aspect of leg and dorsum of foot</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the modification of the deep fascia of the leg and the two muscles attached to it:", "options": [{"label": "A", "text": "A, B, and F respectively", "correct": true}, {"label": "B", "text": "E, C, and G respectively", "correct": false}, {"label": "C", "text": "E, B, and F respectively", "correct": false}, {"label": "D", "text": "E, A, C, and G respectively", "correct": false}], "correct_answer": "A. A, B, and F respectively", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682081229-QTDA044034IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A, B, and F respectively The fascia lata is the deep fascia of the lower limb. It has many modifications, and the one in the Image is the iliotibial tract/ band. The muscles attached to it are the tensor fascia lata and gluteus maximus. The arrow pointing at A corresponds to the iliotibial tract . It is one of the many modifications of fascia lata. It is attached to the capsule of the hip joint, Gerdy’s tubercle of the tibia, and the external lip of the iliac crest. The arrows B and F correspond to the muscles tensor fascia latae and gluteus maximus respectively. They are attached to the iliotibial tract. Hence, it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>There are three modifications of the fascia lata, which are known as the: Iliotibial tract. Intermuscular septa. Saphenous opening.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. The arrow pointing at E corresponds to the tendon of the biceps femoris, and those to C and G are the vastus lateralis and the greater trochanter of the femur. Hence, it is the wrong answer. Option: C. The arrow pointing at E corresponds to the tendon of the biceps femoris. The arrows B and F correspond to the muscles tensor fasciae latae and gluteus maximus, respectively. They are attached to the iliotibial tract. The tendon of the biceps femoris is not a modification of the fascia lata. Hence, it is the wrong answer. Option: D. The arrow pointing at A corresponds to the iliotibial tract. It is one of the many modifications of fascia lata. It is attached to the capsule of the hip joint, Gerdy’s tubercle of the tibia, and the external lip of the iliac crest. The arrows pointing to C and G are the vastus lateralis and the greater trochanter of the femur . Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Saphenous opening (saphenous hiatus, also fossa ovalis) is an oval opening in the upper mid part of the thigh fascia lata. It lies 3–4 cm below and lateral to the pubic tubercle and is about 3 cm long and 1.5 cm wide.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The plexus of nerves arising from the lumbar vertebrae (Image) is said to be embedded within a muscle. What is the original site of this muscle?", "options": [{"label": "A", "text": "Greater trochanter of femur", "correct": false}, {"label": "B", "text": "Transverse process of lumbar vertebra and body of T12 vertebra", "correct": true}, {"label": "C", "text": "Transverse process of the thoracic vertebra and body of the L1 vertebra", "correct": false}, {"label": "D", "text": "Lesser trochanter of femur", "correct": false}], "correct_answer": "B. Transverse process of lumbar vertebra and body of T12 vertebra", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682081231-QTDA044035IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Transverse process of lumbar vertebra and body of T12 vertebra The psoas major muscle is a muscle of the posterior abdominal wall. It has two slips of origin that enclose the lumbar plexus within it.</p>\n<p><strong>Highyeild:</strong></p><p>Psoas major muscle superficial and deep origin sites owing to the presence of branches of the lumbar plexus embedded within it. The superficial part overlies the lumbar plexus and originates from the sides of the T12 and L1-L4 vertebrae and the intervening intervertebral discs. The deep part originates from the transverse process of L1-L5. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Greater trochanter of the femur gives origin to the vastus lateralis. Hence, it is the wrong answer. Option: C. The transverse process of the thoracic vertebra and body of the L1 vertebra doesn’t give rise to a specific muscle with the lumbar plexus embedded within it. Hence, it is the wrong answer. Option: D. The lesser trochanter is the site of the insertion of the psoas major muscle. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Psoas major contributes to flexion in the hip joint. On the lumbar spine, unilateral contraction bends the trunk laterally, while bilateral contraction raises the trunk from its supine position.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The nerves supplying the fascia lata are all except:", "options": [{"label": "A", "text": "Ilioinguinal Nerve", "correct": false}, {"label": "B", "text": "Femoral branch of genitofemoral nerve", "correct": false}, {"label": "C", "text": "Accessory obturator nerve", "correct": true}, {"label": "D", "text": "Femoral cutaneous nerves", "correct": false}], "correct_answer": "C. Accessory obturator nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Accessory obturator nerve Generally, the deep fasciae are very sensitive. As a general rule, the nerve supply of the deep fascia is the same as that of the overlying skin. Hence, the terminal branches of specific nerves innervating the thigh also innervate the fascia lata. The accessory obturator nerve is an occasionally present nerve that supplies the hip joint and the adductor longus. Hence, it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Accessory obturator nerve is an accessory nerve in the lumbar region in about 29% of cases. It arises from the ventral divisions of the third and fourth lumbar nerves. Recent evidence supports that this nerve arises from Dorsal divisions.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The inguinal nerve supplies the part of the fascia lata that is attached to the inguinal ligament. Hence, it is the wrong answer. Option: B. The genitofemoral nerve's femoral branch supplies the fascia lata's upper part. Hence, it is the wrong answer. Option: D. The Femoral cutaneous nerves are of lateral, intermediate, and medial types, and they supply the respective parts of the fascia lata overlying the thigh. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Accessory obturator nerve descends along the medial border of the psoas major, crosses the superior ramus of the pubis, and passes under the pectineus, where it divides into numerous branches. One of these supplies the pectineus, penetrating its deep surface, another is distributed to the hip joint; while a third communicates with the anterior branch of the obturator nerve. Occasionally the accessory obturator nerve is very small and is lost in the capsule of the hip-joint</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The opening in the fascia lata on the medial side of the thigh is guarded by a perforated fascia that is pierced by all except:", "options": [{"label": "A", "text": "Superficial circumflex iliac artery", "correct": false}, {"label": "B", "text": "Superficial circumflex femoral artery", "correct": true}, {"label": "C", "text": "Superficial and deep inguinal lymphatic vessels", "correct": false}, {"label": "D", "text": "Superficial epigastric artery", "correct": false}], "correct_answer": "B. Superficial circumflex femoral artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superficial circumflex femoral artery The fascia lata is the deep fascia of the lower limb. It has many modifications, and one of them is the saphenous opening that is present on the medial side of the thigh . It is guarded by the cribriform fascia that is perforated by numerous structures. Cribriform fascia is pierced by numerous structures, such as the great saphenous vein before it drains into the femoral vein, the superficial epigastric and superficial external pudendal vessels, and a few lymph vessels containing superficial and deep inguinal lymph nodes. The superficial circumflex femoral artery is a branch of the femoral artery that supplies the skin and subcutaneous tissue of the region below the inguinal ligament. It doesn’t pierce the cribriform fascia. Hence, it is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Structures piercing cribriform fascia</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The superficial circumflex iliac artery is a branch of the femoral artery. It supplies the skin and subcutaneous tissue of the region below the inguinal ligament. It pierces the cribriform fascia. Hence, it is the wrong answer. Option: C. The Superficial and deep inguinal lymphatic vessels drain the genital region and lower limb. They pierce the cribriform fascia. Hence, it is the wrong answer. Option: D. The superficial epigastric artery is a femoral artery branch. It supplies the superficial inguinal lymph nodes and skin of the anterior abdominal wall. It pierces the cribriform fascia. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>The femoral artery is palpable in the femoral triangle inferior to the inguinal ligament midway between the anterior superior iliac spine and the pubic symphysis. The femoral artery passes vertically through the femoral triangle and continues down the thigh in the adductor canal. It leaves the canal through the adductor hiatus in the adductor magnus muscle and becomes the popliteal artery behind the knee.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following explains the Image given below with reference to a modification of the fascia lata?", "options": [{"label": "A", "text": "Femoral Hernia", "correct": true}, {"label": "B", "text": "Pyomyositis", "correct": false}, {"label": "C", "text": "Inguinal hernia", "correct": false}, {"label": "D", "text": "Neurofibroma", "correct": false}], "correct_answer": "A. Femoral Hernia", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682081255-QTDA044038IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Femoral Hernia The image is a case of a femoral hernia. It occurs when adipose tissue or a part of the intestine pokes through into your groin at the top of the medial side of the thigh. It pushes through a weak part along the abdominal wall into the femoral canal.</p>\n<p><strong>Highyeild:</strong></p><p>Femoral hernia is a type of indirect hernia . The hernia content passes through the femoral canal and the saphenous opening to poke the upper medial side of the thigh or lower abdomen . The saphenous opening is a modification of the fascia lata. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Pyomyositis is a rare bacterial infection of the skeletal muscle. It is caused by the Staphylococcus aureus The signs and symptoms include pain and tenderness of the affected muscle, fever, and abscess formation. The muscle involved here is the tensor fascia lata. Hence, it is often accompanied by arthritis of the hip joint (this muscle is attached to the iliotibial tract attached to the hip capsule). The bacteria can travel through the bloodstream and can affect other skeletal muscles of the body. Hence, it is the wrong answer. Option: C. I nguinal hernia is of both direct and indirect types. It occurs along the pubic region and passes along the inguinal canal . Hence, it is the wrong answer. Option: D. Neurofibroma is a nerve tumour that forms soft bumps on or under the skin. It can develop within a major or minor nerve anywhere in the body. It is not related to the fascia lata. Hence, it is the wrong answer.</p>\n<p><strong>Extraedge:</strong></p><p>Common hernias in female location</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 48 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which is the most superior structure at the hilum of the left lung?", "options": [{"label": "A", "text": "Pulmonary Vein", "correct": false}, {"label": "B", "text": "Pulmonary artery", "correct": true}, {"label": "C", "text": "Bronchus", "correct": false}, {"label": "D", "text": "Bronchial artery", "correct": false}], "correct_answer": "B. Pulmonary artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pulmonary artery ARRANGEMENT OF STRUCTURES IN THE HILUM Of LEFT LUNG (above to down) Pulmonary artery Left Principal bronchus Inferior Pulmonary vein</p>\n<p><strong>Highyeild:</strong></p><p>The arrangement of structures in the roots of the lungs is as follows: From before backward (it is more or less similar on two sides): Pulmonary Vein (Superior) Pulmonary artery Bronchus (left principal bronchus on the left side, eparterial, and hyparterial bronchus on the right side). Structures in the root of the left and right lung</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Pulmonary Vein Inferior pulmonary veins are located inferiorly in the hilum of the left lung. Option C. Bronchus The left principal bronchus is located between the Pulmonary artery and the inferior pulmonary vein in the hilum of the left lung from above to down. Option D. Bronchial artery The chief structures composing the root of each lung are arranged similarly from the front to the back on each side. This means that the upper of the two pulmonary veins is located anteriorly, the pulmonary artery is in the middle, and the bronchus and bronchial vessels are located posteriorly. Left side: From posterior to anterior side: Single bronchus with bronchial vessels and posterior pulmonary plexus along its rear wall. Pulmonary artery in the middle area placed above the bronchus Superior and inferior pulmonary veins in the anterior part. Anterior pulmonary plexus, lymph nodes, and lymph vessels in the anterior and inferior parts.</p>\n<p><strong>Extraedge:</strong></p><p>The visceral-parietal reflection surrounding the root of the lung extends downwards from the hilum to near the base of the lower lobe in a sleeve-like fold called the pulmonary ligament. The lower rounded edge of this is sometimes referred to as the inferior pulmonary ligament. At the lower edge of each lung, the pleural layers come into contact with each other and terminate in a free-curved edge. The pulmonary ligaments anchor the larger lower lobes of the lungs in position and prevent potential torsion.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following are related to the mediastinal part of the right lung?", "options": [{"label": "A", "text": "Arch of Aorta", "correct": false}, {"label": "B", "text": "SVC", "correct": true}, {"label": "C", "text": "Subclavian artery", "correct": false}, {"label": "D", "text": "Left ventricle", "correct": false}], "correct_answer": "B. SVC", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>SVC The mediastinal surface of the right lung is related to the following structures: Superiorly: groove for the azygos vein where it arches over the root of the right lung more superiorly, track for the esophagus vertically up to the apex Anteriorly: groove for the superior vena cava progressing vertically; a groove joins the track for the azygos vein posteriorly and grooves for the subclavian and brachiocephalic vein superiorly. Anteroinferiorly: the cardiac impression: is much shallower than the equivalent impression on the left lung horizontal fissure runs obliquely and inferiorly across the cardiac impression a groove for the inferior vena cava running vertically down from the root one end of the oblique fissure lies anterior to the track for the inferior vena cava Inferiorly: the pulmonary ligament the lower part of a vertically-running groove for the esophagus Posteriorly: a groove for the esophagus running vertically downwards immediately posterior to the lung root more posteriorly in the superior third of the lung, the oblique fissure.</p>\n<p><strong>Highyeild:</strong></p><p>Structures forming the right mediastinal surface of the lung: The suitable mediastinal surface mainly consists of the right atrium. Above the right atrium are present superior vena cava and right brachiocephalic vein. Behind these structures are present the trachea and esophagus. The azygos vein, a large venous channel, runs upwards along the side of the vertebral column and arches over the root of the right lung to terminate into the superior vena cava. Three neural structures, viz. (a) right phrenic nerve, (b) right vagus nerve, and (c) right sympathetic chain. Structures related to the mediastinal surface of the right lung.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Arch of Aorta Option C. Subclavian artery Option D. Left ventricle Arch of the Aorta, Subclavian artery, and left ventricle are all related to the mediastinal surface of the left lung. The mediastinal surface of the right lung is related to the following structures: Superiorly: deep groove for the arch of the aorta more superiorly is a vertical groove for the subclavian artery Superoanteriorly: start of groove for the arch of aorta projecting posteriorly over the root of the lung Superoposteriorly : oblique fissure passing from hilum Anteroinferiorly: cardiac impression; deeper than on the right side across the cardiac surface projects one end of the oblique fissure in an anteroinferior direction. Inferiorly : pulmonary ligament Posteriorly : vertically descending groove for the arch of the aorta</p>\n<p><strong>Extraedge:</strong></p><p>Structures forming the left mediastinal surface of the lung: The left ventricle and aorta are the main structures forming the left surface of the mediastinum. Aorta ascends at first, arches over the left lung root, and then descends behind the lung root. Three great vessels (brachiocephalic trunk, left common carotid artery, and left subclavian vein) arise from the aortic arch and ascend to the neck's root. The esophagus, as it descends through the thorax, shifts to the left behind the heart and gently crosses the line of the descending aorta. Three neural structures, viz. (a) left phrenic nerve, (b) left vagus nerve, and (c) left sympathetic chain. Structures related to the mediastinal surface of the left lung.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which is not a lobe of the lung?", "options": [{"label": "A", "text": "Azygos", "correct": true}, {"label": "B", "text": "Superior", "correct": false}, {"label": "C", "text": "Inferior", "correct": false}, {"label": "D", "text": "Lingula", "correct": false}], "correct_answer": "A. Azygos", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Azygos Azygos lobe is an anatomically separated part of the upper lobe and not a proper or accessory lobe of the lung as it doesn't have an artery, vein or bronchi. Lobes of Lung</p>\n<p><strong>Highyeild:</strong></p><p>The lobe of Azygos vein : Sometimes the medial part of the superior lobe is partially separated by a fissure of variable length, which contains the terminal part of the azygos vein, enclosed in the free margin of a mesentery derived from the mediastinal pleura. This is termed the lobe of the azygos vein . It varies in size and sometimes includes the apex of the lung.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Superior The right lung has three lobes: superior, inferior, and middle. Option C. Inferior The left lung has two lobes: superior and inferior. Option D. Lingula Lingula is the portion of the left upper lobe. The lingula is a tongue-shaped projection of the left lung below the cardiac notch. It corresponds to the middle lobe of the right lung.</p>\n<p><strong>Extraedge:</strong></p><p>Identification of the completeness of the fissure: It is essential before performing lobectomy (i.e., removal of the lobe of the lung because individuals with incomplete fissures are more prone to develop postoperative air leakage than those with wide apertures).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Bronchopulmonary segments in right and left lungs:", "options": [{"label": "A", "text": "9,11", "correct": false}, {"label": "B", "text": "11,9", "correct": false}, {"label": "C", "text": "10,10", "correct": true}, {"label": "D", "text": "8,10", "correct": false}], "correct_answer": "C. 10,10", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>10,10 There are ten segments on the right side, and ten on the left side Bronchopulmonary segments are well-defined anatomical segments aerated by tertiary/segmental bronchus. These are pyramidal, with the apex directed towards the hilum and the base directed towards the periphery, having their arterial supply, but adjacent bronchopulmonary segments share venous drainage.</p>\n<p><strong>Highyeild:</strong></p><p>Characteristic features of Bronchopulmonary segments of the lung: It is a subdivision of the lung lobe. It is pyramidal with an apex directed towards the hilum and a base towards the surface of the lung. It is surrounded by connective tissue. The segmental (tertiary) bronchus aerates it. Each segment has its artery, a segmental pulmonary artery branch. Each segment has its lymphatic drainage and autonomic supply. Thus, bronchopulmonary segments are the well-defined anatomical, functional, and surgical units of the lungs.</p>\n<p><strong>Extraedge:</strong></p><p>The segmental veins (the tributaries of pulmonary veins) run in the intersegmental planes of the connective tissue in between bronchopulmonary segments.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An inhaled foreign body is likely to lodge in the right lung due to the following features EXCEPT:", "options": [{"label": "A", "text": "The right lung is shorter, and the broader left lung", "correct": true}, {"label": "B", "text": "The right principal bronchus is more vertical than the left bronchus", "correct": false}, {"label": "C", "text": "Tracheal bifurcation directs the foreign body to the right lung", "correct": false}, {"label": "D", "text": "Right inferior lobar bronchus is in continuation with the principal bronchus", "correct": false}], "correct_answer": "A. The right lung is shorter, and the broader left lung", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The right lung is shorter, and the broader left lung Foreign bodies are more likely to lodge in the right lung because the right principal bronchus (not the lung) is shorter, broader, and more vertical.</p>\n<p><strong>Highyeild:</strong></p><p>Features of Right and left bronchus Right Bronchus Left Bronchus DEFINITION Right branch of the inferior end of the trachea is known as right bronchus Left branch of the inferior end of the trachea is known as left bronchus LENGTH Short Long DIVISION Usually divides before Usually divides after WIDTH Wider Narrower ANGLE 20 to 30 degree angle 40 to 60 degree angle. LOCATED AS More vertical More angular LUNG Right bronchus goes to the right lung Left bronchus goes to the left lung</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. The right principal bronchus is more vertical than the left one. The right main bronchus is more comprehensive, shorter, and more vertical than the left main bronchus; its mean length is 1.09 cm. It enters the root of the right lung at approximately the fifth thoracic vertebra. Option C. Tracheal bifurcation directs the foreign body to the right lung. Tracheal bifurcation directs the foreign body to the right lung because the long axis of the correct principal bronchus deviates about 25° from the long axis of the trachea. In contrast, the long axis of the left principal deviates about 45° from the long axis of the the trachea. Option D. Right inferior lobar bronchus is in continuation with the principal bronchus. The right lower lobe bronchus is a lobar (secondary) bronchus that is the continuation of the bronchus intermedius distally to the origin of the right middle lobe bronchus.</p>\n<p><strong>Extraedge:</strong></p><p>Aspiration of a foreign body into the right principal bronchus: The inhaled foreign bodies usually enter in the right principal bronchus because it is shorter, wider, and in line with the trachea. Since the inhaled foreign particles tend to enter the right principal bronchus, hence in the right lung. As a result, lung abscess occurs more commonly in the right lung.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Bronchopulmonary segments are aerated by which of the following bronchi?", "options": [{"label": "A", "text": "Secondary Bronchi", "correct": false}, {"label": "B", "text": "Tertiary bronchi", "correct": true}, {"label": "C", "text": "Terminal bronchioles", "correct": false}, {"label": "D", "text": "Respiratory bronchioles", "correct": false}], "correct_answer": "B. Tertiary bronchi", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tertiary bronchi The trachea divides into the left main bronchus, which supplies the left lung, and the right main bronchus, which supplies the right lung. As they enter the lungs, these primary bronchi branch into secondary bronchi known as lobar bronchi, which supply each lung lobe. These, in turn, give rise to tertiary bronchi (tertiary meaning \"third\"), known as segmental bronchi, which supply each bronchopulmonary segment. A segmental bronchus supplies a structurally separate and functionally independent unit of lung tissue called a bronchopulmonary segment.</p>\n<p><strong>Highyeild:</strong></p><p>The arrangement of bronchopulmonary segments permits the resection of abscesses and localized primary lung malignancy while retaining the standard functioning parts of the lung. Secondary pulmonary lobules, Progressive subdivisions of the bronchi occur within each bronchopulmonary segment, and the bronchi become increasingly narrow. All intrapulmonary bronchi are kept patent by cartilaginous plates that decline in size and number and disappear when bronchi become bronchioles (less than 1 mm in diameter).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Secondary Bronchi The trachea divides into the left main bronchus , which supplies the left lung, and the right main bronchus, which supplies the right lung. As they enter the lungs, these primary bronchi branch into secondary bronchi known as lobar bronchi, which supply each lung lobe. Secondary bronchi, also called lobar bronchi, are located near the middle of the lungs. There is one secondary branch per lobe of the lung. The right lung has three secondary bronchi, and the left has two. Option C. Terminal bronchi The terminal bronchioles are the most distal segment of the conducting zone. Bronchioles open into short pieces called terminal bronchioles, which are thin-walled branches of the bronchioles. Terminal bronchioles transition into respiratory bronchioles. Option D. Respiratory bronchioles The respiratory bronchioles are the narrowest airways of the lungs, 0.5 mm across. The respiratory bronchioles deliver air to the exchange surfaces of the lungs. They are interrupted by alveoli which are thin-walled evaginations. Alveolar ducts are sided branches of the respiratory bronchioles. The respiratory bronchioles are lined by ciliated columnar epithelium and some non-ciliated cells called club cells .</p>\n<p><strong>Extraedge:</strong></p><p>Bronchospasm , a potentially life-threatening situation, occurs when the smooth muscular tissue of the bronchioles constricts, severely narrowing their diameter. The most common cause of this is asthma. Bronchospasm is commonly treated by oxygen therapy and bronchodilators such as albuterol. Diseases of the bronchioles include asthma, bronchiolitis obliterans, respiratory syncytial virus infections, and influenza. The medical condition of inflammation of the bronchioles is termed bronchiolitis .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following are characteristics of a bronchopulmonary segment EXCEPT:", "options": [{"label": "A", "text": "It is surgically resectable", "correct": false}, {"label": "B", "text": "It is named according to the segmental bronchus supplying it", "correct": false}, {"label": "C", "text": "It is drained by an independent intrasegmental branch of pulmonary vein", "correct": true}, {"label": "D", "text": "It is the largest subdivision of a lobe", "correct": false}], "correct_answer": "C. It is drained by an independent intrasegmental branch of pulmonary vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>It is drained by an independent intrasegmental branch of pulmonary vein The Bronchopulmonary segment is pyramidal, with its apex directed towards the root of the lung. Each segment has a segmental bronchus, segmental artery, autonomic nerves, and lymph vessels. The segmental venules lie in the connective tissue between adjacent pulmonary units of bronchopulmonary segments. Bronchopulmonary segment</p>\n<p><strong>Highyeild:</strong></p><p>There are ten bronchopulmonary segments in the right lung: three in the superior lobe, two in the middle lobe, and five in the inferior lobe. Some segments may fuse in the left lung to form usually eight to nine segments (four to five in the upper lobe and four to five in the lower lobe).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. It is surgically resectable Bronchopulmonary segments are well-defined anatomic, functional, and surgical sectors of the lung Option B. It is named according to the segmental bronchus supplying it The trachea divides into the left main bronchus, which supplies the left lung, and the right main bronchus, which supplies the right lung. As they enter the lungs, these primary bronchi branch into secondary bronchi known as lobar bronchi, which supply each lung lobe. These, in turn, give rise to tertiary bronchi (tertiary meaning \"third\"), known as segmental bronchi, which supply each bronchopulmonary segment. Option D. It is the largest subdivision of a lobe The Bronchopulmonary segment is the largest subdivision of a lobe.</p>\n<p><strong>Extraedge:</strong></p><p>Usually, the infection of the bronchopulmonary segment remains restricted to it, although tuberculosis and bronchogenic carcinoma may spread from one segment to another. Visualizing the interior of the bronchi through a bronchoscope passed through the mouth and trachea; the procedure is called bronchoscopy.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which statement best describes the medial compartment of the thigh?", "options": [{"label": "A", "text": "Adductor magnus, longus and brevis insert onto the linea aspera", "correct": true}, {"label": "B", "text": "The obturator nerve innervates all the muscles of the medial compartment", "correct": false}, {"label": "C", "text": "All the muscles of the medial compartment take their origin from the ischium", "correct": false}, {"label": "D", "text": "The obturator nerve is split into anterior and posterior divisions by adductor longus", "correct": false}], "correct_answer": "A. Adductor magnus, longus and brevis insert onto the linea aspera", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Adductor magnus, longus and brevis insert onto the linea aspera All three adductor muscles insert onto the linea aspera. The hamstring position of the adductor magnus inserts on the adductor tubercle above the medial femoral epicondyle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. The obturator nerve innervates all the muscles of the medial compartment. Pectineus is a muscle of the medial compartment but is innervated by the femoral nerve . Its action is flexion and adduction of the thigh at the hip. Option C . All the medial compartment muscles originate from the ischium. All muscles of the medial compartment take their origin from the public bone . They are the three adductors, pectineus, obturator externus and gracilis. Muscles of the medial compartment of the thigh ' Option D. The obturator nerve is split into anterior and posterior divisions by the adductor longus. The obturator nerve splits into anterior and posterior divisions separated by adductor brevis. The obturator nerve is formed from the anterior division of the anterior primary rami of L2-L4.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In the medial compartment of the thigh, which of the following is the true statement?", "options": [{"label": "A", "text": "Gracilis extends & laterally rotates the hip joint", "correct": false}, {"label": "B", "text": "The contents are separated from the posterior compartment by the Posterior Intermuscular septum", "correct": true}, {"label": "C", "text": "Obturator nerve is formed by dorsal divisions of ventral rami of L2,3,4", "correct": false}, {"label": "D", "text": "Adductor longus forms Roof of adductor canal", "correct": false}], "correct_answer": "B. The contents are separated from the posterior compartment by the Posterior Intermuscular septum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The contents are separated from the posterior compartment by the Posterior Intermuscular septum The posterior compartment of the thigh is separated from the anterior compartment by the lateral intermuscular septum and the medial compartment by the posterior intermuscular septum.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Gracilis extends & laterally rotates the hip joint. The Gracilis muscle flexes, medially rotate and adducts the hip. Option, C. Obturator nerve is formed by dorsal divisions of ventral rami of L2,3,4. The ventral division of the ventral rami of L2,3,4 forms the obturator nerve. Option D. Adductor longus forms Roof of adductor canal The following muscular structures border the adductor canal: Anteromedial/ Roof : Sartorius. Lateral: Vastus medialis. Posterior: Adductor longus and adductor magnus. Adductor canal boundaries and content</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The capsule of the knee joint is supplied by:", "options": [{"label": "A", "text": "Genital branch of genitofemoral nerve", "correct": false}, {"label": "B", "text": "Femoral branch of genitofemoral nerve", "correct": false}, {"label": "C", "text": "Genicular branch of obturator nerve", "correct": true}, {"label": "D", "text": "Anterior branch of obturator nerve", "correct": false}], "correct_answer": "C. Genicular branch of obturator nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Genicular branch of obturator nerve The knee joint capsule is supplied by a genicular branch of the obturator nerve which pierces the oblique popliteal ligament.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A . The genital branch of the genitofemoral nerve, also known as the external spermatic nerve in males, is a nerve in the abdomen that arises from the genitofemoral nerve. The genital branch supplies the cremaster muscle, anterior scrotal skin in males, and the skin of the mons pubis and labia majora in females. Option B. The femoral branch passes underneath the inguinal ligament, travelling through the lateral muscular compartment of the femoral canal, where it innervates the skin of the upper leg. Option D. Anterior branch of the obturator nerve leaves the pelvis in front of the obturator externus and descends anterior to the adductor brevis and posterior to the pectineus and adductor longus; at the lower border of the latter muscle, it communicates with the anterior cutaneous and saphenous branches of the femoral nerve, forming a kind of plexus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The adductor canal lateral boundary is formed by:", "options": [{"label": "A", "text": "Adductor Longus", "correct": false}, {"label": "B", "text": "Rectus medialis", "correct": false}, {"label": "C", "text": "Vastus lateralis", "correct": false}, {"label": "D", "text": "Vastus medialis", "correct": true}], "correct_answer": "D. Vastus medialis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Vastus medialis Adductor canal The adductor canal is an intermuscular tunnel occupying the distal two-thirds of the medial aspect of the thigh. It starts at the apex of the femoral triangle and extends distally as far as the distal attachment of the tendon of the adductor magnus. The adductor canal is bordered by the following muscular structures: Anteromedial/ Roof : Sartorius. Lateral: Vastus medialis. Posterior: Adductor longus and adductor magnus. The adductor canal contains Femoral artery and vein, the descending genicular and muscular branches of the femoral artery and their corresponding venous tributaries, the saphenous nerve, and the nerve to vastus medialis. The femoral vessels pass from the adductor canal into the popliteal fossa via the adductor hiatus, an opening in the tendon of the adductor magnus adjacent to the femoral shaft, two-thirds of the way down the adductor canal. Adductor canal boundaries and content</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 63-year-old woman with a grade 2 endometrioid adenocarcinoma of the uterus diagnosed by endometrial biopsy is taken to the operating room for surgical treatment with a total abdominal hysterectomy, bilateral salpingo-oophorectomy, and pelvic and paraaortic lymphadenectomy. No complaints are noted intraoperatively. On postoperative day 1, the patient complains of numbness in her medial thigh. Your neurologic examination suggests the absence of cutaneous sensation to the medial thigh and an inability to adduct her hip. Which of the following is the most likely etiology for this clinical presentation?", "options": [{"label": "A", "text": "Femoral Nerve Injury", "correct": false}, {"label": "B", "text": "Genitofemoral nerve injury", "correct": false}, {"label": "C", "text": "Pudendal nerve injury", "correct": false}, {"label": "D", "text": "Obturator nerve injury", "correct": true}], "correct_answer": "D. Obturator nerve injury", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Obturator nerve injury The obturator nerve (L2-L4) is most commonly injured during retroperitoneal surgery for gynecologic malignancies. In this case, a pelvic lymph node dissection for endometrial cancer involves a retroperitoneal dissection into the obturator fossa to remove the obturator lymph nodes. The nodal tissue of the obturator fossa obscures the location of the obturator nerve and predisposes it to injury. Postoperatively, patients with an injury to the obturator nerve will present with sensory loss to the upper medial thigh and motor weakness in the hip adductors. The obturator nerve is the nerve of the medial compartment of the thigh ; If an obturator nerve injury is recognised intraoperatively, immediate repair is the recommended treatment. However, with postoperative recognition, as in this case, treatment includes physiotherapy with neuromuscular electrical stimulation, electromyographic biofeedback, and exercise. Obturator nerve injury is a highly treatable condition, and complete recovery of motor strength is generally the result after physical therapy. Explanation for incorrect options:- Option A . The femoral nerve is the most commonly injured nerve at the time of gynecologic surgical procedures. It is usually damaged during laparotomy from inappropriate placement of lateral retractor blades. Patients with injury to the femoral nerve will present with diminished or absent deep tendon reflexes and an inability to straight leg raise, flex at the hips, or extend the knee. There may also be a loss of cutaneous sensation over the anterior thigh and the medial aspect of the thigh and calf. Option B. The genitofemoral nerve (L1, L2) runs along the ventral surface of the psoas muscle, lateral to the external iliac artery. If removed or damaged, patients present with numbness of the ipsilateral mons pubis, labia majora, and skin overlying the femoral triangle . This nerve conducts sensory information only, thus no loss in motor function. Option C. The pudendal nerve (S2-S4) also conducts sensory information—injury to the pudendal nerve results in a loss of sensation to the perineum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following muscle is supplied by the obturator nerve?", "options": [{"label": "A", "text": "Gluteus Medius", "correct": false}, {"label": "B", "text": "Obturator internus", "correct": false}, {"label": "C", "text": "Sartorius", "correct": false}, {"label": "D", "text": "Adductor brevis", "correct": true}], "correct_answer": "D. Adductor brevis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Adductor brevis The adductor brevis is the muscle of the medial compartment supplied by the obturator nerve. Obturator nerve branches</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Gluteus Medius The Superior gluteal nerve supplies gluteus medius. Option B. Obturator internus The nerve to the obturator internus and superior gemellus is formed from the anterior (ventral) divisions of the L5, S1 and S2 nerve roots of the sacral plexus. Option C. Sartorius The femoral nerve supplies Sartorius . It is a flexor of the hip and knee and balances the hip bone on the femur along with other long muscles connecting the hip bone to the leg.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The medial compartment of the thigh is supplied by which nerve?", "options": [{"label": "A", "text": "Tibial Nerve", "correct": false}, {"label": "B", "text": "Obturator nerve", "correct": true}, {"label": "C", "text": "Femoral nerve", "correct": false}, {"label": "D", "text": "Common peroneal", "correct": false}], "correct_answer": "B. Obturator nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Obturator nerve Obturator nerve Nerve roots: L2-L4 Motor functions: Innervates the muscles of the medial compartment of the thigh (obturator externus, adductor longus, adductor brevis, adductor magnus and gracilis). Sensory functions: Cutaneous branches of the obturator nerve innervate the skin of the medial thigh. Obturator nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. The tibial nerve provides innervation to the lower leg and foot muscles. Option C. The femoral nerve is a nerve in the thigh that supplies the skin on the upper thigh, inner leg, and the muscles that extend the knee. Option D. Common peroneal nerve-Anterior compartment of the leg, lateral compartment of the leg, extensor digitorum brevis</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "From the given Transverse Section taken through the middle of the thigh, find out the false statement:", "options": [{"label": "A", "text": "Represents Vastus Intermedius", "correct": false}, {"label": "B", "text": "Is a Composite muscle", "correct": false}, {"label": "C", "text": "Represents Femoral artery", "correct": false}, {"label": "D", "text": "Represents obturator nerve", "correct": true}], "correct_answer": "D. Represents obturator nerve", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683682110370-QTDA045008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Represents obturator nerve Option D. Represents sciatic nerve emerging below the piriformis – root value L4, 5, S1, 2, 3. Explanation for incorrect options:- Option A . Vastus intermedius – supplied by the femoral nerve Option B. Adductor magnus – Hamstring part supplied by Tibial nerve, Adductor part supplied by Posterior division of obturator nerve. So, Adductor Magnus is a composite muscle. Option C. Femoral artery in the adductor canal.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 18 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The nerve supply of 1st lumbrical is:", "options": [{"label": "A", "text": "Median Nerve", "correct": true}, {"label": "B", "text": "Radial Nerve", "correct": false}, {"label": "C", "text": "Ulnar Nerve", "correct": false}, {"label": "D", "text": "Both A & B", "correct": false}], "correct_answer": "A. Median Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Median Nerve 1st & 2nd lumbrical - supplied by median nerve , while 3rd & 4th lumbrical by the deep branch of ulnar nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Camparative analysis between ulnar claw hand and hand of benediction Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Compression of the nerve within the carpal tunnel produces an inability to:", "options": [{"label": "A", "text": "Extend The Thumb", "correct": false}, {"label": "B", "text": "Adduct the Thumb", "correct": false}, {"label": "C", "text": "Oppose the Thumb", "correct": true}, {"label": "D", "text": "Both A & B", "correct": false}], "correct_answer": "C. Oppose the Thumb", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Oppose the Thumb The opposition of thumb - opponens pollicis - median nerve In Carpal tunnel syndrome, the median nerve gets compressed under the flexor retinaculum, leading to paralysis of the muscles of the thenar eminence. It is called an ‘ape-like or monkey-like hand ’. There is loss of sensation in lateral 3½ digits including nail beds. The median nerve is the ‘eye of the hand’. There is little clawing of the index and middle fingers also. Explanation for incorrect options: - Option: A. Extend The Thumb Extension of thumb - all extensor muscles - radial nerve Option: B. Adduct the thumb Adduction of thumb - adductor pollicis - ulnar nerve</p>\n<p><strong>Highyeild:</strong></p><p>Camparative analysis between ulnar claw hand and hand of benediction Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 19-year male presents with complaints of hypoesthesia and wasting of the thenar eminence in his right hand. The nerve most likely to be affected in this case is:", "options": [{"label": "A", "text": "Musculocutaneous Nerve", "correct": false}, {"label": "B", "text": "Median Nerve", "correct": true}, {"label": "C", "text": "Ulnar Nerve", "correct": false}, {"label": "D", "text": "Radial Nerve", "correct": false}], "correct_answer": "B. Median Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Median Nerve Median nerve compression in the carpal tunnel at the wrist leads to Carpal Tunnel syndrome. This syndrome consists of motor, sensory, vasomotor, and trophic symptoms in the hand caused by compression of the median nerve in the carpal tunnel. Examination reveals wasting of thenar eminence ( ape-like hand ), and hypoesthesia to light touch on the palmar aspect of lateral 3½ digits. However, the skin over the thenar eminence is not affected as the branch of the median nerve supplying it arises in the forearm. Symptoms and signs Findings indicative of CTS Age 40-60 years Gender Female > males Risk Factors Obesity, Diabetes mellitus, hypothyroidism, rheumatoid arthritis, Chronic Renal failure, pregnancy Occupation More in occupation involving repeated hand movements or vibrations Sensory symptoms Pain Paresthesia Numbness Classic or Probable pattern of Katz Hand Diagram Flicks sign Motor symptoms Hand Clumsiness Weakness of Thumb Atrophy of Thenar Muscles Autonomic symptoms Swelling or Feeling of Tightness in Hand Temperature change Difference in skin color Difference in sympathetic skin response of median to ulnar nerve Provocative tests Phalen's test Tinel sign Manual Carpal Compression test</p>\n<p><strong>Highyeild:</strong></p><p>Camparative analysis between ulnar claw hand and hand of benediction Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Musculocutaneous Nerve Isolated injury to the musculocutaneous nerve is a rare occurrence . Associated signs and symptoms of an isolated musculocutaneous neuropathy may include weakness in elbow flexion or shoulder flexion, atrophy of the biceps brachii, and pain or paresthesia at the lateral forearm Option: C. Ulnar nerve Ulnar nerve innervates hypothenar muscles and not thenar muscles. Option: D . Radial nerve Radial nerve innervates the extensor group of muscles not the thenar muscles.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Select the most appropriate statement regarding the Median nerve:", "options": [{"label": "A", "text": "Arises from the posterior and medial cords of the brachial plexus", "correct": false}, {"label": "B", "text": "Passes from the medial to the lateral; side of the brachial artery in the arm", "correct": false}, {"label": "C", "text": "Gives no muscular branches in the arm", "correct": true}, {"label": "D", "text": "Enters the forearm muscles by passing between the two heads of flexor carpi ulnaris", "correct": false}], "correct_answer": "C. Gives no muscular branches in the arm", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Gives no muscular branches in the arm The only branch the median nerve gives in the arm is a branch to the elbow joint.</p>\n<p><strong>Highyeild:</strong></p><p>Camparative analysis between ulnar claw hand and hand of benediction Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Arises from the posterior and medial cords of the brachial plexus The median nerve arises from the medial and lateral cords of the brachial plexus. The posterior cord gives rise to the radial nerve. Option: B. Passes from the medial to the lateral; side of the brachial artery in the arm. The median nerve passes from the lateral to the medial side of the brachial artery in the arm. The commencement of the nerve is lateral to the artery and then passes in front of the brachial artery and descends to lie medial to it at the elbow. Option: D. Enters the forearm muscles by passing between the two heads of flexor carpi ulnaris The median nerve enters the forearm by passing between the two heads of pronator teres.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A young boy who was driving a motorcycle at high speed collided with a tree and was thrown on his right shoulder. Though there was no fracture, his right arm was medially rotated and his forearm pronated. The following facts concerning this patient are correct, except:", "options": [{"label": "A", "text": "The injury was at Erb’s point", "correct": false}, {"label": "B", "text": "A lesion of C-5 and C-6 was present", "correct": false}, {"label": "C", "text": "The median and ulnar nerve was affected", "correct": true}, {"label": "D", "text": "Supraspinatus and infraspinatus, subclavius, and biceps brachii were paralyzed", "correct": false}], "correct_answer": "C. The median and ulnar nerve was affected", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The median and ulnar nerve was affected If the Median and Ulnar nerves are both affected, then the boy must present with features of a complete claw hand along with paralysis of all flexor muscles of the foramen and intrinsic muscles of the hand.</p>\n<p><strong>Highyeild:</strong></p><p>Camparative analysis between ulnar claw hand and hand of benediction Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The injury was at Erb’s point Option: B. A lesion of C-5 and C-6 was present Erb’s palsy is due to injury of C-5,6 roots at Erb’s point and doesn't involve the ulnar nerve(C7,8; T1) Option: D. Supraspinatus and infraspinatus, subclavius, and biceps brachii were paralyzed Only the C6 root has been compromised. Injury of the suprascapular nerve (C5,6) leads to paralysis of the supraspinatus and infraspinatus muscles. Nerve to subclavius (C5,6) is involved. There is a partial injury of the musculocutaneous nerve (C5,6,7) which leads to paralysis of the biceps brachii muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 15 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 74-year-old woman is admitted to the emergency department after stumbling over her pet dog. Radiographic examination reveals a fracture of the upper third of the right radius, with distal fragments of the radius and hand pronated. The proximal end of the fractured radius deviates laterally. Which of the following muscles is primarily responsible for the lateral deviation?", "options": [{"label": "A", "text": "Pronator Teres", "correct": false}, {"label": "B", "text": "Supinator", "correct": true}, {"label": "C", "text": "Pronator Quadratus", "correct": false}, {"label": "D", "text": "Brachioradialis", "correct": false}], "correct_answer": "B. Supinator", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Supinator The fracture line of the upper third of the radius lies between the bony attachments of the supinator and the pronator teres muscles. The proximal fragment deviates laterally by the unopposed contraction of the supinator muscle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Pronator Teres Option: C. Pronator quadratus The distal radial fragment and hand are pronated due to unopposed contraction of pronator teres and pronator quadratus muscles. Option: D. Brachioradialis The brachioradialis inserts distally on the radius. The brachialis inserts on the coronoid process of the ulna and would not be involved in the lateral deviation of the radius.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old woman motorcyclist, propelled over the handlebars of her bike by an encounter with a rut in the road, lands on the point of one shoulder. The woman is taken by ambulance to the emergency department. During the physical examination, the arm appears swollen, pale, and cool. Any movement of the arm causes severe pain. Radiographic examination reveals a fracture and a large hematoma, leading to the diagnosis of Volkmann’s ischemic contracture. At which of the following locations has the fracture most likely occurred?", "options": [{"label": "A", "text": "Surgical neck of humerus", "correct": false}, {"label": "B", "text": "Radial groove of the humerus", "correct": false}, {"label": "C", "text": "Supracondylar line of humerus", "correct": true}, {"label": "D", "text": "Olecranon", "correct": false}], "correct_answer": "C. Supracondylar line of humerus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Supracondylar line of humerus A fracture of the humerus just proximal to the epicondyles is called a supracondylar fracture . This is the most common cause of a Volkmann ischemic fracture. The sharp bony fragment often lacerates the brachial artery , with bleeding into the flexor compartment. Decreased arterial supply to the compartment results in ischemia. Bleeding into the compartment causes greatly increased pressure, first blocking venous outflow from the compartment, then reducing the arterial flow into the compartment. The ischemic muscles undergo contracture. A humeral fracture is sometimes placed in a cast from shoulder to wrist, often concealing the ischemia until major tissue loss occurs.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Surgical neck of humerus Fracture of the surgical neck endangers the axillary nerve and posterior humeral circumflex artery, although not ischemic contracture. Option: B . Radial groove of the humerus Fracture of the humerus in the spiral groove can injure the radial nerve and profunda brachii artery. Option: D. Olecranon Fracture of the olecranon does not result in Volkmann’s contracture, although the triceps brachii can displace the distal fracture fragment of the ulna .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 27-year-old patient presents with an inability to draw the scapula forward and downward because of paralysis of the pectoralis minor. Which of the following would most likely be a cause of his condition?", "options": [{"label": "A", "text": "Fracture of the clavicle", "correct": false}, {"label": "B", "text": "Injury to the posterior cord of the brachial plexus", "correct": false}, {"label": "C", "text": "Fracture of the coracoid process", "correct": true}, {"label": "D", "text": "Axillary nerve injury", "correct": false}], "correct_answer": "C. Fracture of the coracoid process", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fracture of the coracoid process Pectoralis minor is paralyzed because it is inserted on the coracoid process of the scapula. Pectoralis Minor Origin: Second to the fifth ribs Insertion: Coracoid process Innervation : Medial and Lateral pectoral nerves Action : Depresses the shoulder and forms the anterior wall of the axilla</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Fracture of the clavicle Pectoralis minor has no attachment on the clavicle. Option: B. Injury to the posterior cord of the brachial plexus Pectoralis minor is not innervated by any branch from the posterior cord of the brachial plexus. Option: D. Axillary nerve injury Axillary nerve innervates the Deltoid and Teres minor muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "If the structure highlighted by red color is calcified, which of the following muscles is most likely to get paralyzed?", "options": [{"label": "A", "text": "Deltoid", "correct": false}, {"label": "B", "text": "Teres major", "correct": false}, {"label": "C", "text": "Teres minor", "correct": false}, {"label": "D", "text": "Infraspinatus", "correct": true}], "correct_answer": "D. Infraspinatus", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683729762-QTDA102004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Infraspinatus The Suprascapular notch transmits the suprascapular nerve below the superior transverse ligament, whereas the suprascapular artery and vein run over the ligament. The suprascapular nerve supplies the supraspinatus and infraspinatus muscles, so the Infraspinatus muscle will be paralyzed in the above condition.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Deltoid Option: C . Teres minor The axillary nerve innervates the deltoid and teres minor Option: B. Teres major The subscapular nerve innervates the teres major and subscapularis muscles.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 19-year-old man is brought to the emergency department after dislocating his shoulder while playing soccer. Following the reduction of the dislocation, he has pain over the dorsal region of the shoulder and cannot abduct the arm normally. MRI of the shoulder shows torn muscles. Which of the following muscles is most likely to have been damaged by this injury?", "options": [{"label": "A", "text": "Coracobrachialis", "correct": false}, {"label": "B", "text": "Long head of triceps", "correct": false}, {"label": "C", "text": "Pectoralis minor", "correct": false}, {"label": "D", "text": "Supraspinatus", "correct": true}], "correct_answer": "D. Supraspinatus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Supraspinatus Supraspinatus is one of the rotator cuff muscles. Its tendon is relatively avascular and is often injured when the shoulder is dislocated. This muscle initiates abduction of the arm , and damage would impair this movement.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Coracobrachialis Coracobrachialis causes adduction and flexion of the arm Option: B. Long head of triceps The triceps help in the extension of the elbow. Option: C. Pectoralis minor Pectoralis minor helps in accessory respiratory muscle and to stabilize the scapula.</p>\n<p><strong>Extraedge:</strong></p><p>Muscle Origin on scapula Attachment on humerus Function Innervation Supraspinatus Muscle Supraspinous fossa greater tubercle Abducts the arm Suprascapular nerve (C5) Infraspinatus Muscle Infraspinous fossa greater tubercle Laterally rotates the arm Suprascapular nerve (C5-C6) Teres Minor Muscle Lateral border greater tubercle laterally rotates the arm Axillary nerve (C5) Subscapularis Muscle Subscapular fossa lesser tubercle Medially rotates the arm Subscapular nerve (C5-C6)</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 47-year-old female tennis professional is informed by her physician that she has a rotator cuff injury that will require surgery. He explains that over the years of play, a shoulder ligament has gradually caused severe damage to the underlying muscle. To which of the following ligaments is the physician most likely referring?", "options": [{"label": "A", "text": "Acromioclavicular Ligament", "correct": false}, {"label": "B", "text": "Coracoclavicular ligament", "correct": false}, {"label": "C", "text": "Glenohumeral ligament", "correct": false}, {"label": "D", "text": "Coracoacromial ligament", "correct": true}], "correct_answer": "D. Coracoacromial ligament", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Coracoacromial ligament The coracoacromial ligament prevents superior displacement of the head of the humerus. The ligament can cause inflammation or erosion of the tendon of the supraspinatus muscle as the tendon passes under the ligament. Coracoacromial ligament</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Acromioclavicular Ligament The acromioclavicular ligament , connecting the acromion with the lateral end of the clavicle, is not in contact with the supraspinatus tendon. Option: B. Coracoclavicular ligament The coracoclavicular ligament is located too far anteriorly to impinge upon the supraspinatus tendon. Option: C. Glenohumeral ligament The glenohumeral ligament is located deep to the rotator cuff muscles and would not contribute to injury of the supraspinatus muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 21-year-old woman walks in with shoulder and arm injuries after falling during horseback riding. Examination indicates that she cannot adduct her arm because of paralysis of which of the following muscles?", "options": [{"label": "A", "text": "Teres Minor", "correct": false}, {"label": "B", "text": "Supraspinatus", "correct": false}, {"label": "C", "text": "Latissimus dorsi", "correct": true}, {"label": "D", "text": "Infraspinatus", "correct": false}], "correct_answer": "C. Latissimus dorsi", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Latissimus dorsi Option: C. Latissimus dorsi adducts the arm.</p>\n<p><strong>Highyeild:</strong></p><p>Camparative analysis between ulnar claw hand and hand of benediction Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Teres minor laterally rotates the arm and stabilizes the humerus. Option: B. Supraspinatus abducts the arm. Option: D. Infraspinatus rotates the arm laterally.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 7-Year-old boy builds a treehouse and is brought to the emergency department of a local hospital. On examination, he has weakness in rotating his arm laterally because of an injury of a nerve. Which of the following conditions is most likely to cause a loss of this nerve function?", "options": [{"label": "A", "text": "Injury to the lateral cord of the brachial plexus", "correct": false}, {"label": "B", "text": "Supracondylar fracture humerus", "correct": false}, {"label": "C", "text": "Knife wound on teres major muscle", "correct": false}, {"label": "D", "text": "Inferior dislocation of the head of the humerus.", "correct": true}], "correct_answer": "D. Inferior dislocation of the head of the humerus.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior dislocation of the head of the humerus. Inferior dislocation of the head of the humerus may damage the axillary nerve , which arises from the posterior cord of the brachial plexus, and supplies the deltoid and teres minor muscles which are lateral rotators of the arm.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Injury to the lateral cord of the brachial plexus Injury to the lateral cord of the brachial plexus will damage branches of the lateral cord such as the musculocutaneous, Lateral pectoral nerve, and lateral root of the median nerve. Injury to these nerves doesn't affect the lateral rotation of the arm. Option: B . Supracondylar fracture humerus Supracondylar fracture of the humerus, the nerve injury will be the anterior interosseous nerve not affecting the lateral rotation of the arm. Option: C . Knife wound on teres major muscle Teres major muscle is the medial rotator of an arm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A rock climber falls on his shoulder, resulting in chipping off the lesser tubercle of the humerus. Which of the following structures would most likely have structural and functional damage?", "options": [{"label": "A", "text": "Supraspinatus Muscle", "correct": false}, {"label": "B", "text": "Infraspinatus Muscle", "correct": false}, {"label": "C", "text": "Subscapularis Muscle", "correct": true}, {"label": "D", "text": "Teres minor Muscle", "correct": false}], "correct_answer": "C. Subscapularis Muscle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Subscapularis Muscle The subscapularis muscle is inserted on the lesser tubercle of the humerus.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Supraspinatus Muscle The supraspinatus muscle is attached to the greater tubercle of the scapula Option: B. Infraspinatus muscle The infraspinatus muscle is attached to the greater tubercle of the scapula. Option: D. Teres minor muscle Teres minor muscle is attached to the greater tubercle of the scapula. Rotator Cuff Muscles</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "While carrying a heavy suitcase the downward dislocation of the glenohumeral joint is resisted by the following muscles EXCEPT:", "options": [{"label": "A", "text": "Deltoid", "correct": false}, {"label": "B", "text": "Coracobrachialis", "correct": false}, {"label": "C", "text": "Short head of biceps", "correct": false}, {"label": "D", "text": "Latissimus dorsi", "correct": true}], "correct_answer": "D. Latissimus dorsi", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Latissimus dorsi The axis of the pull of the latissimus dorsi doesn't cross the shoulder joint and cannot have a shunt action on the joint.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Deltoid Option: B. Coracobrachialis Option: C. Short head of biceps Shunt muscles -stabilize the corresponding joint, when not producing movement at the joint. For example; while carrying a heavy suitcase the downward dislocation of the glenohumeral joint is resisted by the muscles like deltoid, coracobrachialis, and short head of biceps.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A man cannot do abduction and internal rotation of the arm. Which of the following muscles is responsible for both movements?", "options": [{"label": "A", "text": "Pectoralis Major", "correct": false}, {"label": "B", "text": "Subscapularis", "correct": false}, {"label": "C", "text": "Deltoid", "correct": true}, {"label": "D", "text": "Teres Major", "correct": false}], "correct_answer": "C. Deltoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deltoid The deltoid muscle is responsible for both abduction at the shoulder joint and internal rotation of the arm DELTOID FIBERS MOVEMENTS Middle (lateral) fibers abduction at shoulder joint Anterior fibers flexion and medial rotation Posterior fibers extension and lateral rotation</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Pectoralis Major Pectoralis major muscle primarily causes flexion, adduction, and Internal rotation of the arm. Option: B. Subscapularis Option: D. Teres major Subscapularis and teres major muscles are not involved in the abduction, though both of them work on the medial rotation of the arm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 16-year-old boy fell from a motorcycle, and his radial nerve was severely damaged because of a fracture of the midshaft of the humerus. Which of the following conditions would most likely result from the accident?", "options": [{"label": "A", "text": "Loss of wrist extension leading to wrist drop", "correct": true}, {"label": "B", "text": "Weakness in pronating the forearm", "correct": false}, {"label": "C", "text": "Sensory loss over the ventral aspect of the thumb", "correct": false}, {"label": "D", "text": "Inability to oppose the thumb", "correct": false}], "correct_answer": "A. Loss of wrist extension leading to wrist drop", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Loss of wrist extension leading to wrist drop Injury to the radial nerve in the mid-shaft region of the humerus results in loss of wrist extension leading to wrist drop.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option : B. Weakness in pronating the forearm Option: C. Sensory loss over the ventral aspect of the thumb Option: D. Inability to oppose the thumb The median nerve innervates the: Pronator teres Pronator quadratus Opponens pollicis muscles The skin over the ventral aspect of the thumb The ulnar nerve innervates the dorsal interosseous muscles, which act to abduct the fingers.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old male arrived at the emergency department with injuries to his left elbow after he fell in a bicycle race. Radiographic and MRI examinations show a fracture of the medial epicondyle and a torn ulnar nerve. Which of the following muscles would be most likely to be paralyzed?", "options": [{"label": "A", "text": "Flexor Digitorum Superficialis", "correct": false}, {"label": "B", "text": "Biceps brachii", "correct": false}, {"label": "C", "text": "Brachioradialis", "correct": false}, {"label": "D", "text": "Flexor carpi ulnaris", "correct": true}], "correct_answer": "D. Flexor carpi ulnaris", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Flexor carpi ulnaris Fracture of the medial epicondyle often causes damage to the ulnar nerve due to position in the groove behind the epicondyle. Ulnar nerve innervates one and a half muscles in the forearm-the flexor carpi ulnaris and the medial half of the flexor digitorum profundus.</p>\n<p><strong>Highyeild:</strong></p><p>Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Flexor Digitorum Superficialis The flexor digitorum superficialis is innervated by the median nerve. Option: B . Biceps brachii The biceps brachii by the musculocutaneous nerve. Option: C . Brachioradialis Radial nerve innervates the brachioradialis muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 35 year old man walks in with a stab wound to the most medial side of the proximal portion of the cubital fossa. Which of the following structures would most likely be damaged?", "options": [{"label": "A", "text": "Biceps Brachii Tendon", "correct": false}, {"label": "B", "text": "Radial Nerve", "correct": false}, {"label": "C", "text": "Brachial Artery", "correct": false}, {"label": "D", "text": "Median Nerve", "correct": true}], "correct_answer": "D. Median Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Median Nerve The most medial content of the cubital fossa is the Median nerve , which has been compromised. Option: A. Biceps Brachii Tendon Option: B . Radial nerve Option: C . Brachial artery The contents of the cubital fossa from lateral to medial side are: Radial nerve Biceps tendon Artery (brachial) Median nerve Mnemonic(R-BAM) Content of Cubital Fossa (From lateral to medial)</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old male is admitted to the hospital after accidentally walking through a plate glass door in a bar while intoxicated. Physical examination shows multiple lacerations to the upper limb, with the inability to flex the distal interphalangeal joints of the 4th and 5th digits. Which of the following muscles is most likely affected?", "options": [{"label": "A", "text": "Flexor Digitorum Profundus", "correct": true}, {"label": "B", "text": "Flexor digitorum superficialis", "correct": false}, {"label": "C", "text": "Lumbricals", "correct": false}, {"label": "D", "text": "Interossei", "correct": false}], "correct_answer": "A. Flexor Digitorum Profundus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Flexor Digitorum Profundus Loss of flexion at the distal interphalangeal joint occurs due to loss of function of FDP (Flexor digitorum profundus) Flexor digitorum profundus is dually innervated by the ulnar nerve to the medial phalanges and the median nerve for the lateral phalanges Because of the superficial course of the ulnar nerve, it is vulnerable to injury by laceration. Such an injury would result in an ability to flex distal interphalangeal joints of the 4th and 5th digits.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Flexor digitorum superficialis The flexor digitorum superficialis is innervated by the median nerve only, and the course of this nerve runs too deep to be affected by lacerations. Option: C. Lumbricals The lumbrical function is to flex MCP (Metacarpophalangeal) joints and assist in extending the IP joints. Option: D. Interossei The interossei muscles adduct and abduct the fingers (along with the MCP flexion)</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient comes in complaining that she cannot flex her hand at the joint marked by a black arrow in the Image. Which of the following muscles appears to be paralyzed on further examination of her finger?", "options": [{"label": "A", "text": "Palmar Interossei", "correct": false}, {"label": "B", "text": "Dorsal nterossei", "correct": false}, {"label": "C", "text": "Flexor Digitorum Profundus", "correct": false}, {"label": "D", "text": "Flexor Digitorum Superficialis", "correct": true}], "correct_answer": "D. Flexor Digitorum Superficialis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683729764-QTDA102016IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Flexor Digitorum Superficialis The flexor digitorum superficialis muscle flexes the proximal interphalangeal joints</p>\n<p><strong>Highyeild:</strong></p><p>Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers no explanation</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A . Palmar Interossei Option: B . Dorsal interossei The palmar and dorsal interossei and lumbricals can flex metacarpophalangeal joints and extend the interphalangeal joints. The palmar interossei adduct the fingers The dorsal interossei abduct the fingers Option: C. Flexor digitorum profundus The flexor digitorum profundus muscle flexes the Distal interphalangeal joints</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 31-year-old worker comes with tenosynovitis which is the result of a deep penetrated wound in the palm by a big nail. O/E has an infection in the ulnar bursa. This infection most likely resulted in necrosis of which of the following tendons?", "options": [{"label": "A", "text": "Tendon of flexor carpi ulnaris", "correct": false}, {"label": "B", "text": "Tendon of flexor pollicis longus", "correct": false}, {"label": "C", "text": "Tendon of flexor digitorum profundus", "correct": true}, {"label": "D", "text": "Tendon of palmaris longus", "correct": false}], "correct_answer": "C. Tendon of flexor digitorum profundus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tendon of flexor digitorum profundus Ulnar bursa or common synovial flexor sheath, contains the tendons of both flexor digitorum superficialis and profundus muscles. Ulnar and Radial Bursa</p>\n<p><strong>Highyeild:</strong></p><p>Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers no explanation</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Tendon of flexor carpi ulnaris Option: B. . Tendon of flexor pollicis longus Radial bursa envelopes the tendon of the flexor pollicis longus. Option: D. Tendon of palmaris longus The tendons of flexor carpi ulnaris and palmaris longus are not contained in ulnar bursa.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "After radical mastectomy, there was an injury to the long thoracic nerve. The integrity of the nerve can be tested at the bedside by asking the patient to:", "options": [{"label": "A", "text": "Shrug the Shoulders", "correct": false}, {"label": "B", "text": "Raise the arm above the head on the affected side", "correct": true}, {"label": "C", "text": "Touch the opposite shoulder", "correct": false}, {"label": "D", "text": "Lift a heavy object from the ground.", "correct": false}], "correct_answer": "B. Raise the arm above the head on the affected side", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Raise the arm above the head on the affected side NERVE MUSCLE MOVEMENT Long thoracic nerve Serratus anterior Overhead abduction Spinal accessory nerve Trapezius Shrugging the shoulder Lateral and medial pectoral Nerves Pectoralis major Touching the opposite shoulder</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Pronator teres syndrome is due to the involvement of which of the following nerve?", "options": [{"label": "A", "text": "Radial Nerve", "correct": false}, {"label": "B", "text": "Anterior interosseous nerve", "correct": false}, {"label": "C", "text": "Ulnar nerve", "correct": false}, {"label": "D", "text": "Median nerve", "correct": true}], "correct_answer": "D. Median nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Median nerve Pronator teres syndrome Median nerve entrapment syndrome Compressed between the heads of the pronator teres near the elbow Clinical features Pain and tenderness in the proximal aspect of the anterior forearm. Hypoesthesia of palmer aspects of the lateral three-and-a-half fingers and adjacent palm</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A muscle in the upper limb that contains a sesamoid bone is:", "options": [{"label": "A", "text": "Extensor pollicis longus", "correct": false}, {"label": "B", "text": "Flexor pollicis longus", "correct": false}, {"label": "C", "text": "Flexor carpi radialis", "correct": false}, {"label": "D", "text": "Flexor carpi ulnaris", "correct": true}], "correct_answer": "D. Flexor carpi ulnaris", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Flexor carpi ulnaris Sesamoid bones small rounded masses of bones located in some of the muscle tendons at points where they are subjected to great pressure. Important Sites of Sesamoid Bones: In the ear: The lenticular process of the incus is a sesamoid bone and therefore is considered the fourth ossicle of the middle ear. In the hand: Two sesamoid bones in the distal portions of the first metacarpal bone (within the tendons of adductor pollicis and flexor pollicis brevis). In the wrist: The pisiform of the wrist is a sesamoid bone (within the tendon of flexor carpi ulnaris), develops at the age of (9–12). In the knee: The patella (within the quadriceps tendon) Fabella: in the lateral head of gastrocnemius behind the knee joint. Around Cuboid bone : Sesamoid bone in the tendon of peroneus longus where it binds around the cuboid bone. In the foot: Two sesamoid bones in the distal portions of the first metatarsal bone (within the tendons of flexor hallucis brevis.)</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which muscle originates from the tendon of another muscle?", "options": [{"label": "A", "text": "Palmaris Longus", "correct": false}, {"label": "B", "text": "PCR", "correct": false}, {"label": "C", "text": "Lumbricals", "correct": true}, {"label": "D", "text": "Adductor Pollicis", "correct": false}], "correct_answer": "C. Lumbricals", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lumbricals Lumbricals take origin from flexor digitorum profundus tendon. Lumbrical muscles originating from FDP tendons</p>\n<p><strong>Highyeild:</strong></p><p>Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 40 year old male met with a road traffic accident. The patient was not able to adduct his ring and index finger. Which palmar interossei are affected?", "options": [{"label": "A", "text": "1st and 2nd", "correct": false}, {"label": "B", "text": "1st and 3rd", "correct": false}, {"label": "C", "text": "2nd and 3rd", "correct": true}, {"label": "D", "text": "2nd and 4th", "correct": false}], "correct_answer": "C. 2nd and 3rd", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2nd and 3rd No palmar interossei is present for the middle finger. So, index finger has 2nd palmar interossei & ring finger has 3rd palmar interossei The 1st palmar interossei muscle is frequently missing as the thumb has its own adductor muscle. Intrinsic muscles of hand</p>\n<p><strong>Highyeild:</strong></p><p>Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p><strong>Extraedge:</strong></p><p>Movements at 2nd to 5th joints and muscles producing them: Flexion: Interossei and lumbricals Extension: Extensors of the fingers Abduction: Dorsal interossei Adduction: Palmar interossei Circumduction: Above muscles in sequence.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The medial boundary of the anatomical snuffbox is formed by:", "options": [{"label": "A", "text": "Extensor Pollicis Brevis", "correct": false}, {"label": "B", "text": "Extensor carpi radialis longus", "correct": false}, {"label": "C", "text": "Extensor pollicis longus", "correct": true}, {"label": "D", "text": "Extensor carpi radialis brevis", "correct": false}], "correct_answer": "C. Extensor pollicis longus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Extensor pollicis longus Anatomical snuffbox A triangular depression on the posterolateral side of the wrist. It is seen best when the thumb is extended. Boundaries Anterolaterally by tendons of the abductor pollicis longus and extensor pollicis brevis Posteromedially by the tendon of the extensor pollicis longus Floor formed by the scaphoid, the trapezium, and base of 1st metacarpal. Roof formed by skin and superficial fascia. Boundaries of Anatomical Snuff Box Clinical significance of anatomical snuff box: The pulsations of radial artery can be felt in the anatomical box. The tenderness in the anatomical box indicates a fracture of the scaphoid bone. The cephalic vein at this site is often used for giving intravenous fluids. The superficial branches of the radial nerve can be rolled over the tendon of the extensor pollicis longus.</p>\n<p><strong>Highyeild:</strong></p><p>Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the deformity shown in the figure:", "options": [{"label": "A", "text": "Mallet Finger", "correct": false}, {"label": "B", "text": "Swan neck deformity", "correct": false}, {"label": "C", "text": "Boutonniere deformity", "correct": true}, {"label": "D", "text": "Jersey finger deformity", "correct": false}], "correct_answer": "C. Boutonniere deformity", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683729815-QTDA102024IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Boutonniere deformity Boutonnière (button-hole) deformity : It is opposite to mallet finger deformity. It is characterized by flexion of proximal interphalangeal (PIP) joint and hyperextension of the distal phalanx. It occurs when the flexed PIP joint pokes through the extensor expansion following the rupture of its central portion of dorsal digital expansion.</p>\n<p><strong>Highyeild:</strong></p><p>Ulnar claw Hand of benediction Nerve involved Lesion of ulnar nerve at the wrist Lesion of the median nerve at the elbow or at the wrist Typical presentation Appears in long standing cases Appears when patient attempts to make a fist Digits affected Little and ring Middle and index Muscles paralysed • Medial two lumbricals • Lateral two lumbricals • Lateral half of the FDP Movements involved Unopposed extension t the MCP joints Unopposed flexion at the IP joints Inability to flex at the MCP and IP joints of the middle and index fingers Voluntary flexion at the MCP and IP joints of the ring and little fingers</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Mallet Finger Mallet's finger is an injury to the tendons that straightens the end joint of a finger or thumb. Although it is also known as \"baseball finger,\" this injury can happen to anyone when an object like a ball strikes the tip of a finger or thumb and forces it to bend. As a result, you are not able to straighten the tip of your finger or thumb on your own. Option: B. Swan neck deformity Swan neck deformity is characterized by proximal interphalangeal (PIP) joint hyperextension and distal interphalangeal (DIP) joint flexion . There is also reciprocal flexion noted of the metacarpophalangeal (MCP) joint. This is a result of an imbalance of the extensor mechanism of the digit. Option: D. Jersey finger deformity Jersey finger (also known as rugby finger) is an avulsion of the flexor digitorium profundus tendon (FDP) from its distal insertion on the distal phalanx</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A card test is done to check the function of:", "options": [{"label": "A", "text": "Lumbricals", "correct": false}, {"label": "B", "text": "Palmar Interossei", "correct": true}, {"label": "C", "text": "Dorsal Interossei", "correct": false}, {"label": "D", "text": "Adductor Pollicis", "correct": false}], "correct_answer": "B. Palmar Interossei", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Palmar Interossei Card Test Palmar interossei adduct the fingers towards the center of the third digit or middle finger. They are tested by placing a piece of paper/card between the fingers.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "De-Quervain's tenosynovitis affects:", "options": [{"label": "A", "text": "FPL and FPB", "correct": false}, {"label": "B", "text": "EPL and APL", "correct": false}, {"label": "C", "text": "EPB and APL", "correct": true}, {"label": "D", "text": "FDP and FDS", "correct": false}], "correct_answer": "C. EPB and APL", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>EPB and APL The synovial lining of the tendons of extensor pollicis brevis (EPB) and abductor pollicis longus (APL) can get inflamed due to repetitive strain and can lead to a painful condition called De Quervain’s tenosynovitis. Movement of the thumb can aggravate pain in this condition.</p>\n<p><strong>Extraedge:</strong></p><p>Finklestein test is used for diagnosis</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 36 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "All are true about proximal humerus attachment, except:", "options": [{"label": "A", "text": "Supraspinatus at lesser tubercle", "correct": true}, {"label": "B", "text": "Subscapularis at the lesser tubercle", "correct": false}, {"label": "C", "text": "Teres minor at greater tubercle", "correct": false}, {"label": "D", "text": "Infraspinatus at greater tubercle", "correct": false}], "correct_answer": "A. Supraspinatus at lesser tubercle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Supraspinatus at lesser tubercle The four muscles attaching at the proximal humerus along with their attachments are as in the table below. Supraspinatous attaches at GREATER tubercle, not lesser.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following bones are involved in the formation of wrist joints; except:", "options": [{"label": "A", "text": "Scaphoid", "correct": false}, {"label": "B", "text": "Ulna", "correct": true}, {"label": "C", "text": "Radius", "correct": false}, {"label": "D", "text": "Triquetral", "correct": false}], "correct_answer": "B. Ulna", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ulna Wrist joint The wrist joint is the synovial joint of the ellipsoid variety between the lower end of the radius and an articular disc of the inferior radioulnar joint proximally and three lateral bones of the proximal row of carpus, i.e. scaphoid, lunate and triquetral distally. The pisiform does not play a role in the radiocarpal articulation. It is a sesamoid bone acting as a pulley for flexor carpi ulnaris. Wrist Joint</p>\n<p><strong>Highyeild:</strong></p><p>Articular Surfaces Upper The inferior surface of the lower end of the radius. Articular disc of the inferior radioulnar joint. Lower Scaphoid Lunate Triquetral bones</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "False about clavicle:", "options": [{"label": "A", "text": "Ossifies From Membrane", "correct": false}, {"label": "B", "text": "Horizontal Bone", "correct": false}, {"label": "C", "text": "No Medullary Cavity", "correct": false}, {"label": "D", "text": "Most common site of fracture is the junction of medial 1/3 and lateral 2/3", "correct": true}], "correct_answer": "D. Most common site of fracture is the junction of medial 1/3 and lateral 2/3", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Most common site of fracture is the junction of medial 1/3 and lateral 2/3 Clavicle Peculiarities of the Clavicle It is the only long bone that lies horizontally. It is subcutaneous throughout It is the first bone to start ossifying. It is the only long bone which ossifies in the membrane. It is the only long bone which has two primary centres of ossification. There is no medullary cavity. It is occasionally pierced by the middle supraclavicular nerve. It receives the weight of the upper limb via lateral one-third through the coracoclavicular ligament and transmits the weight of the upper limb to the axial skeleton via the medial two-thirds part.</p>\n<p><strong>Highyeild:</strong></p><p>The shaft is divisible into the lateral one-third and the medial two-thirds. The most common site of fracture is the junction between the two curvatures of the bone, which is the weakest point. The lateral fragment is displaced downwards by the weight of the limb as trapezius muscle alone is unable to support the weight of the upper limb.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The superior angle of the scapula lies at which level?", "options": [{"label": "A", "text": "T7", "correct": false}, {"label": "B", "text": "T12", "correct": false}, {"label": "C", "text": "T2", "correct": true}, {"label": "D", "text": "C5", "correct": false}], "correct_answer": "C. T2", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>T2 It's a factual question. The superior angle of the scapula lies at the T2 level. Other important landmarks are mentioned below.</p>\n<p><strong>Extraedge:</strong></p><p>Important Anatomical Levels Anteroposterior diameter of the inlet of the thorax—5 cm. Transverse diameter of the inlet of the thorax—10 cm. Suprasternal notch—T2 vertebra. Sternal angle—disc between T4 and T5 vertebrae. 2nd costal cartilage articulates with the sternum. Xiphisternal joint—T9 vertebra. Subcostal angle—between sternal attachments of 7th costal cartilages. Vertebra prominence—7th cervical spine. The superior angle of the scapula—level of the T2 spine. The root of the spine of the scapula—level of T3 spine. The inferior angle of the scapula—level of the T7 spine. Length of the oesophagus—25 cm: (Cervical part—4 cm, Thoracic part—20 cm, Abdominal part—1.25 cm) Beginning of oesophagus—C6 vertebra Termination of the oesophagus—T11 vertebra Beginning of trachea—C6 vertebra: Length of trachea—10-15 cm. Bifurcation of trachea—upper border of T5 vertebra. Length of right principal bronchus—2.5 cm. Length of left principal bronchus—5 cm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The long head of biceps attached to:", "options": [{"label": "A", "text": "Coracoid Process", "correct": false}, {"label": "B", "text": "Supraglenoid Tubercle", "correct": true}, {"label": "C", "text": "Acromion Process", "correct": false}, {"label": "D", "text": "Bicipital Groove", "correct": false}], "correct_answer": "B. Supraglenoid Tubercle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Supraglenoid Tubercle Biceps brachii muscle: Origins - The short head originates from the coracoid process. The long head originates from the supraglenoid tubercle. Mnemonic: “You walk shorter to a street corner. You ride longer on a superhighway” Insertion - Radial tuberosity and bicipital aponeurosis into deep fascia on the medial part of the forearm Biceps Brachii</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not intracapsular?", "options": [{"label": "A", "text": "Coronoid Fossa", "correct": false}, {"label": "B", "text": "Radial Fossa", "correct": false}, {"label": "C", "text": "Olecranon Fossa", "correct": false}, {"label": "D", "text": "Lateral Epicondyle", "correct": true}], "correct_answer": "D. Lateral Epicondyle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral Epicondyle Capsular ligament of the elbow joint: Superiorly- it is attached to the lower end of the humerus in such a way that the capitulum, the trochlea, the radial fossa, the coronoid fossa and the olecranon fossa are intracapsular. Inferomedially- it is attached to the margin of the trochlear notch of the ulna except laterally Inferolaterally- it is attached to the annular ligament of the superior radioulnar joint. The synovial membrane lines the capsule and the fossae, named above.</p>\n<p><strong>Extraedge:</strong></p><p>Clinical Correlations Tennis elbow (lateral epicondylitis) is caused by a chronic inflammation or irritation of the origin (tendon) of the extensor muscles of the forearm from the lateral epicondyle of the humerus as a result of repetitive strain. It is a painful condition and common in tennis players and violinists. Golfer's elbow (medial epicondylitis) is a painful condition caused by a small tear or an inflammation or irritation in the origin of the flexor muscles of the forearm from the medial epicondyle. Avoidance of repetitive bending (flexing) of the forearm is advised in order to not compress the ulnar nerve Nursemaid's elbow or pulled elbow is a radial head subluxation and occurs in toddlers when the child is lifted by the wrist. It is caused by a partial tear (or loose) of the annular ligament and thus the radial head to slip out of position.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which nerve is not related to the humerus bone?", "options": [{"label": "A", "text": "Axillary", "correct": false}, {"label": "B", "text": "Radial", "correct": false}, {"label": "C", "text": "Ulnar", "correct": false}, {"label": "D", "text": "Musculocutaneous", "correct": true}], "correct_answer": "D. Musculocutaneous", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Musculocutaneous Nerves Related to Humerus Surgical neck- axillary nerve Spiral groove-radial nerve Behind medial epicondyle- ulnar nerve</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about radius bone is:", "options": [{"label": "A", "text": "Radial Groove Present", "correct": false}, {"label": "B", "text": "Major contributions to the wrist joint", "correct": true}, {"label": "C", "text": "Radial artery lies medial to the styloid process of the radius", "correct": false}, {"label": "D", "text": "Medial bone of the for", "correct": false}], "correct_answer": "B. Major contributions to the wrist joint", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Major contributions to the wrist joint The radius bone forms take part in the formation of the wrist joint along with the carpal bones scaphoid and lunate.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Radial Groove Presen- A radial groove is present in the humerus bone Option: C. Radial artery lies medial to the styloid process of the radiu- The radial artery is palpated against the anterior surface of the lower end of the radius Option: D. Medial bone of the forearm - The radius bone is the lateral bone of the forearm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which is the largest carpal bone?", "options": [{"label": "A", "text": "Trapezoid", "correct": false}, {"label": "B", "text": "Scaphoid", "correct": false}, {"label": "C", "text": "Lunate", "correct": false}, {"label": "D", "text": "Capitate", "correct": true}], "correct_answer": "D. Capitate", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Capitate The Capitate is the largest carpal bone and also is the earliest to appear among the carpal bones.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The most commonly fractured carpal bone is:", "options": [{"label": "A", "text": "Hamate", "correct": false}, {"label": "B", "text": "Lunate", "correct": false}, {"label": "C", "text": "Scaphoid", "correct": true}, {"label": "D", "text": "Capitate", "correct": false}], "correct_answer": "C. Scaphoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Scaphoid Fracture of the scaphoid is quite common. The bone fractures through the waist at right angles to its long axis. The fracture is caused by a fall on the outstretched hand, or on the tips of the fingers. This causes tenderness and swelling in the anatomical snuffbox, and pain on longitudinal percussion of the thumb and index finger. The residual disability is more marked in the midcarpal joint than in the wrist joint. The importance of the fracture lies in its liability to non-union, and avascular necrosis (as it receives retrograde blood supply)of the body of the bone with pain in the anatomical snuffbox.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Articulation of pisiform bone is with, which of the following carpal bone.", "options": [{"label": "A", "text": "Triquetral", "correct": true}, {"label": "B", "text": "Lunate", "correct": false}, {"label": "C", "text": "Scaphoid", "correct": false}, {"label": "D", "text": "Trapezoid", "correct": false}], "correct_answer": "A. Triquetral", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Triquetral Important points regarding of Articulations of carpal bones: The scaphoid: Radius, lunate, trapezium, trapezoid capitate. The lunate: Radius, scaphoid, capitate, hamate and triquetral. The triquetral: Pisiform, lunate, hamate and an articular disc of the inferior radioulnar joint. The pisiform articulates only with the triquetral. The trapezium: Scaphoid, 1st and 2nd metacarpals and trapezoid. The trapezoid: Scaphoid, trapezium, 2nd metacarpal and capitate. The capitate: Scaphoid, lunate, hamate, 2nd, 3rd and 4th metacarpals and trapezoid. The hamate: Lunate, triquetral, capitate, and 4th and 5th metacarpals. Articulations of carpal bones</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Ossification centre for lunate appears at:", "options": [{"label": "A", "text": "Birth", "correct": false}, {"label": "B", "text": "2nd year", "correct": false}, {"label": "C", "text": "4th year", "correct": true}, {"label": "D", "text": "6th year", "correct": false}], "correct_answer": "C. 4th year", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4th year Ossification centre for lunate-4th year</p>\n<p><strong>Highyeild:</strong></p><p>Age of Ossification of Carpal bones</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "False statement about 1st metacarpal:", "options": [{"label": "A", "text": "Shortest and stoutest of all metacarpals", "correct": false}, {"label": "B", "text": "Does not articulate with any other metacarpal", "correct": false}, {"label": "C", "text": "Rotate medially through 90 degrees with respect to other metacarpals", "correct": false}, {"label": "D", "text": "Base is formed by condylar articular surface for scaphoid", "correct": true}], "correct_answer": "D. Base is formed by condylar articular surface for scaphoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Base is formed by condylar articular surface for scaphoid Characteristics of 1st Metacarpal Bone: It is the shortes t and stoutest of all metacarpal bones. The base is occupied by a Concavo-convex articular surface for the trapezium. The dorsal surface of the shaft is uniformly convex. The head is less convex and broader from side to side than the heads of other metacarpals. The ulnar and radial corners of the palmar surface show impressions for sesamoid bones. The first metacarpal bone (lying on a more anterior plane) is rotated medially through 90°relative to the other metacarpals. As a result of this rotation, the movements of the thumb take place at right angles to those of other digits. It does not articulate with any other metacarpal bone.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following structures in the scapula is palpable in the infraclavicular fossa.", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": true}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "C. C", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683770513-QTDA103014IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C A- infra glenoid tubercleB- acromion processC- coracoid processD- inferior angle of scapula Tip of the coracoid process is palpable 2.5cm in the infraclavicular fossa. Scapula bone</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The action of the question marked muscle in the given image.", "options": [{"label": "A", "text": "Flexion of MCP joint", "correct": true}, {"label": "B", "text": "Extension of MCP joint", "correct": false}, {"label": "C", "text": "Flexion of IP joint", "correct": false}, {"label": "D", "text": "Abduction of MCP joint", "correct": false}], "correct_answer": "A. Flexion of MCP joint", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/questionImage-1690539729526-QTDA103015.jpg"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Flexion of MCP joint Given muscle-is lumbricals Action of lumbricals : Flex metacarpophalangeal joints and extend interphalangeal joints of 2nd–5th digits.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "‘Dropped shoulder' occurs due to paralysis of:", "options": [{"label": "A", "text": "Teres Minor", "correct": false}, {"label": "B", "text": "Deltoid", "correct": false}, {"label": "C", "text": "Teres Major", "correct": false}, {"label": "D", "text": "Trapezius", "correct": true}], "correct_answer": "D. Trapezius", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Trapezius Action of Trapezius muscle Upper fibres act along with levator scapulae, and elevate the scapula, as in shrugging. Upper fibres of both sides extend the neck Middle fibres act along with rhomboids, and retract the scapula Upper and lower fibres act along with serratus anterior and rotate the scapula forwards around the chest wall thus playing an important role in abduction of the arm beyond 90. Steadies the scapula. Trapezius Muscle</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The Trapezius muscle is attached to all structures, except", "options": [{"label": "A", "text": "First Rib", "correct": true}, {"label": "B", "text": "Clavicle", "correct": false}, {"label": "C", "text": "Scapula", "correct": false}, {"label": "D", "text": "Occipital", "correct": false}], "correct_answer": "A. First Rib", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>First Rib The attachment of the trapezius is mentioned in the table below.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 50-year-old female had undergone mastectomy for Ca Breast. After the mastectomy, the patient was not able to extend, adduct and internally rotate the arm. Nerve supply to which of the following muscles could have been damaged?", "options": [{"label": "A", "text": "Pectoralis Major", "correct": false}, {"label": "B", "text": "Teres Minor", "correct": false}, {"label": "C", "text": "Latissimus Dorsi", "correct": true}, {"label": "D", "text": "Long head of Triceps", "correct": false}], "correct_answer": "C. Latissimus Dorsi", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Latissimus Dorsi In the given case, after the surgery for breast cancer, the latissimus dorsi muscle is damaged. Action of latissimus dorsi - extension, adduction and medial rotation of arm.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Pectoralis Major - Action of pectoralis major - flexion, adduction and medial rotation of arm. Option: B. Teres minor - Teres minor muscle laterally rotate the arm. Option: D. Long head of Triceps - Long head of Triceps extends, adducts arm, Extends shoulder.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 28 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A male patient was brought to the hospital after RTA. Emergency treatment was started but the patient ultimately died. The age estimation of the person was done using the clavicle bone in which it was seen that the medial end has a fused ossification centre. What will be the age of the person?", "options": [{"label": "A", "text": "12 Years", "correct": false}, {"label": "B", "text": "17 years", "correct": false}, {"label": "C", "text": "21 years", "correct": false}, {"label": "D", "text": "25 years", "correct": true}], "correct_answer": "D. 25 years", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>25 years Ossification of the Clavicle bone The clavicle is the first bone in the body to ossify , Except for its medial end, it ossifies in the membrane. It ossifies of two primary centres and one secondary centre. The two primary centres appear in the shaft between the fifth and sixth weeks of intrauterine life and fuse about the 45th day. The secondary centre for the medial end appears during 15–17 years and fuses with the shaft during 21–22 years. Occasionally, there may be a secondary centre for the acromial end. So the best correct Option is D</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In the following bone given in the image, the highlighted red structure provides the origin of the muscle which can be tested by palpating its fibres during adduction and medial rotation of the flexed shoulder against resistance. Which other muscle also originates along with this from the same marked structure?", "options": [{"label": "A", "text": "Short head of biceps brachii", "correct": true}, {"label": "B", "text": "Lateral head of triceps", "correct": false}, {"label": "C", "text": "Pectoralis minor", "correct": false}, {"label": "D", "text": "Long head of biceps brachii", "correct": false}], "correct_answer": "A. Short head of biceps brachii", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683798338-QTDA104002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Short head of biceps brachii The given description in the question for testing the muscle by palpating it during adduction and medial rotation of the flexed shoulder against resistance suggests the coracobrachialis muscle. It originates from the marked structure i.e. coracoid process. The other muscle which originates from the coracoid process also is the short head of the biceps brachii. Hence, the answer is option A.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B . Lateral head of triceps - The lateral head of the Triceps Extends the forearm. Option: C . Pectoralis mino - Stabilizes the scapula by drawing it inferiorly and anteriorly against the thoracic wall, and raises ribs in inspiration. Option: D . Long head of biceps brachi - Flexes the elbow and Supinates the Radio-ulnar joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were asked about the relation of the following marked structure in the given image. Which of the following options represents the correct answer?", "options": [{"label": "A", "text": "Suprascapular nerve through the foramen and sub-scapular vessels below.", "correct": false}, {"label": "B", "text": "Suprascapular nerve above the foramen and suprascapular vessel through the foramen.", "correct": false}, {"label": "C", "text": "Sub-scapular nerve below the foramen and suprascapular vessel through the foramen.", "correct": false}, {"label": "D", "text": "Suprascapular nerve through the foramen and suprascapular vessels above the foramen.", "correct": true}], "correct_answer": "D. Suprascapular nerve through the foramen and suprascapular vessels above the foramen.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683798338-QTDA104003IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Suprascapular nerve through the foramen and suprascapular vessels above the foramen. In the given question, the marked structure is a superior transverse scapular ligament or suprascapular ligament. The superior transverse scapular (suprascapular) ligament converts the scapular notch into a foramen. The suprascapular nerve traverses through the foramen and the suprascapular vessels cross above the ligament. Hence, the correct answer to this question will be option D.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Suprascapular nerve through the foramen and sub-scapular vessels below- is a wrong statement as the subscapular vessels do not travel below the foramen. Option: B. Suprascapular nerve above the foramen and suprascapular vessel through the foramen- is not correct. Option: C. Sub-scapular nerve below the foramen and suprascapular vessel through the foramen- is also not correct.</p>\n<p><strong>Extraedge:</strong></p><p>Tennis elbow (lateral epicondylitis) is caused by a chronic inflammation or irritation of the origin ( tendon ) of the extensor muscles of the forearm from the lateral epicondyle of the humerus as a result of repetitive strain. It is a painful condition and common in tennis players and violinists. Golfer's elbow (medial epicondylitis) is a painful condition caused by a small tear or an inflammation or irritation in the origin of the flexor muscles of the forearm from the medial epicondyle. Avoidance of repetitive bending ( flexing ) of the forearm is advised in order to not compress the ulnar nerve. Nursemaid's elbow or pulled elbow is a radial head subluxation and occurs in toddlers when the child is lifted by the wrist. It is caused by a partial tear (or loose) of the annular ligament and thus the radial head to slip out of position.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During learning about the age estimation from the upper end of the humerus, you learnt about the age of beginning of ossification for the head, greater tubercle and lesser tubercle. Which of the following represents the correct order for the ossification of the above three structures?", "options": [{"label": "A", "text": "Head->Lesser Tubercle->Greater Tubercle.", "correct": false}, {"label": "B", "text": "Head->greater tubercle->lesser tubercle.", "correct": true}, {"label": "C", "text": "Greater tubercle->lesser tubercle->head", "correct": false}, {"label": "D", "text": "lesser tubercle->head->greater tubercle.", "correct": false}], "correct_answer": "B. Head->greater tubercle->lesser tubercle.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Head->greater tubercle->lesser tubercle. Ossification of the Upper end of Humerus The proximal humerus and shaft are ossified from four centres: one each in the shaft , head, and greater and lesser tubercles. The centre for the shaft appears near its middle in the eighth week of intrauterine life and gradually extends towards the ends. Most growth occurs at the distal end of the bone. Ossification begins in the head before birth (20%) or in the first 6 months afterwards ; the greater tubercle starts to ossify during the first year in females and the second year in males; the lesser tubercle begins to ossify at about the fifth year. By the sixth year, the centres for the head and tubercles have joined to form a single large epiphysis . The proximal humeral epiphysis fuses with the shaft of the humerus at about the thirteenth or fourteenth year in females, and between the fourteenth to sixteenth year in males.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 22-year-old male patient came to OPD with the complaint as shown in the image. The doctor tells the patient that there is an injury to the nerve supplying the affected muscle. You were posted as an intern there when the professor tells you that this nerve originates from the C5, C6, and C7 roots of the brachial plexus and supplies the affected muscle. Which of the options depicts the insertion of the muscle on the scapula?", "options": [{"label": "A", "text": "Dorsal surface on the medial border of the scapula.", "correct": false}, {"label": "B", "text": "Dorsal surface on the lateral border of the scapula.", "correct": false}, {"label": "C", "text": "Costal surface on the medial border of the scapula.", "correct": true}, {"label": "D", "text": "Costal surface on the lateral border of the scapula.", "correct": false}], "correct_answer": "C. Costal surface on the medial border of the scapula.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683798367-QTDA104005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Costal surface on the medial border of the scapula. The nerve originating from the C5, C6, and C7 nerve roots of the brachial plexus supplies the muscle serratus anterior. Damage to the long Thoracic nerve or serratus anterior weakness can result in winging of the scapula as given in the image. The insertion of the serratus anterior occurs in the form of digitizations on the costal surface of the medial border of the scapula. Hence, the answer to this question will be option C.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A . Dorsal surface on the medial border provides insertion to levator scapulae, rhomboid minor and major in the same order from above to below. Option: B. Dorsal surface on the lateral border provides origin to teres major and teres minor. Option: D. . The costal surface on the lateral border does not give origin or insertion to any muscle.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral Erb's point is at the junction of C5 and C6 roots . (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1) .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the marked structure in the given image and the muscle inserted on it.", "options": [{"label": "A", "text": "Deltoid tubercle, middle fibres of the deltoid.", "correct": false}, {"label": "B", "text": "Deltoid tubercle, middle fibers of trapezius.", "correct": true}, {"label": "C", "text": "Deltoid tuberosity, middle fibres of the deltoid", "correct": false}, {"label": "D", "text": "Deltoid tuberosity, middle fibers of trapezius.", "correct": false}], "correct_answer": "B. Deltoid tubercle, middle fibers of trapezius.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683798404-QTDA104006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deltoid tubercle, middle fibers of trapezius. In the given question, the marked structure is the deltoid tubercle which is present on the spine of the scapula. Middle and inferior fibres of the trapezius muscle, and deltoid muscle, are attached to the deltoid tubercle. The deltoid tubercle marks the beginning of the attachment of the deltoid muscle.</p>\n<p><strong>Extraedge:</strong></p><p>Largest branch of brachial plexus is radial nerve (NEET pattern 2014) Roots of brachial plexus are present in neck region (and not axilla) (NEET Pattern 2013) Arterial supply to brachial plexus is from the branches of subclavian and vertebral Erb's point is at the junction of C5 and C6 roots . (NEET Pattern 2013) Ulnar nerve carries root value: C-7, 8; (T-1) .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The content of the marked structure originates from the supraglenoid tubercle. Which of the following statements regarding the relation and attachment of the other structures around the marked structure is correct?", "options": [{"label": "A", "text": "The medial lip provides attachment to the teres major", "correct": false}, {"label": "B", "text": "The lateral lip provides attachment to the pectoralis major", "correct": false}, {"label": "C", "text": "The content of the grove is the ascending branch of the anterior circumflex humeral artery.", "correct": false}, {"label": "D", "text": "All of the above.", "correct": true}], "correct_answer": "D. All of the above.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683798404-QTDA104007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above. The marked structure in the given image is the intertubercular sulcus or bicipital groove. The content of the bicipital groove is the tendon of the long head of the biceps brachii along with its synovial sheath and ascending branch of the anterior circumflex humeral artery. The medial lip of the bicipital groove provides attachment to the teres major and the lateral lip provides attachment to the pectoralis major. The floor of the bicipital groove provides attachment to latissimus dorsi. Hence, all the statements are correct in the given question.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following options represents the correct option regarding the time of ossification centre appearance of the following structures around the elbow? Radial head Capitulum Lateral epicondyle Medial epicondyle Trochlea Olecranon process Select the correct answer from the given below ciode:", "options": [{"label": "A", "text": "1->3->5->2->4->6", "correct": false}, {"label": "B", "text": "2->1->4->5->6->3", "correct": true}, {"label": "C", "text": "1->4->5->6->3->2", "correct": false}, {"label": "D", "text": "2->1->6->4->5", "correct": false}], "correct_answer": "B. 2->1->4->5->6->3", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>2->1->4->5->6->3 In the given question, the timing for the appearance of the ossification center occurs as follows: Capitulum- 1 year Radial head- 3 year Internal/medial epicondyle- 5 year Trochlea- 7 year Olecranon process- 9 year Lateral/external epicondyle- 11 year Hence the correct sequence will be option B.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During your anatomy class, your professor asks you about the marked structure. Which of the following statement is correct from the given options:", "options": [{"label": "A", "text": "It is attached from the medial aspect of the ulnar tuberosity above to below the radial tuberosity directed downwards.", "correct": false}, {"label": "B", "text": "Oblique cord is sandwiched between the supinator and the FDP and FPL muscles.", "correct": true}, {"label": "C", "text": "Its direction is parallel to the interosseous membrane.", "correct": false}, {"label": "D", "text": "Both A and C.", "correct": false}], "correct_answer": "B. Oblique cord is sandwiched between the supinator and the FDP and FPL muscles.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683798430-QTDA104009IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Oblique cord is sandwiched between the supinator and the FDP and FPL muscles. The oblique cord is a remnant of the elbow stabilizer in quadrupedal primates. The oblique cord is sandwiched between the supinator and the FDP and FPL muscles. it is likely to develop as an intermuscular septum.</p>\n<p><strong>Highyeild:</strong></p><p>Radioulnar joints: Movement and muscles involved Movements Muscles involved Pronation Pronator quadratus (strong pronator), pronator teres (Rapid pronator), brachioradialis Supination Supinator (in extended elbow), Biceps (in flexed elbow), brachioradialis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. It is attached from the medial aspect of the ulnar tuberosity above to below the radial tuberosity directed downwards. The oblique cord of the forearm in humans is a ligament connecting the anterolateral aspect of the ulna proximally to the posteromedial aspect of the radius distally, inserting just below the radial tuberosity . Option: C. Its direction is parallel to the interosseous membrane. Oblique cord fibres run in the opposite direction to those of the Interosseous membrane of the forearm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A male patient was brought to emergency after he fell from his bike on his wrist when a car pushed his bike from the backside. He complains of pain around the wrist. A wrist X-ray was done and is given below which appears to be normal. Which of the following structures are involved in the formation of the wrist joint?", "options": [{"label": "A", "text": "Radius, ulna, scaphoid, lunate", "correct": false}, {"label": "B", "text": "Radius, scaphoid, lunate, TFCC", "correct": false}, {"label": "C", "text": "Radius, scaphoid, lunate, TFCC and triquetrum on ulnar deviation.", "correct": false}, {"label": "D", "text": "Both B and C.", "correct": true}], "correct_answer": "D. Both B and C.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683798433-QTDA104010IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Both B and C. Radius, scaphoid, lunate, TFCC In the given question, an X-ray of the wrist joint is shown which is normal. The bones involved in the formation of wrist joints are: Radius, scaphoid and lunate . Also, the triangular fibrocartilaginous complex TFCC present on the ulna is the main stabilizer of the wrist joint is also involved. Option: C. Radius, scaphoid, lunate, TFCC and triquetrum on ulnar deviation. On ulnar deviation, the triquetrum comes in contact with the TFCC and hence, also contributes to the wrist joint. Hence, the answer will be option D. (D. Both B and C)</p>\n<p><strong>Highyeild:</strong></p><p>Radioulnar joints: Movement and muscles involved Movements Muscles involved Pronation Pronator quadratus (strong pronator), pronator teres (Rapid pronator), brachioradialis Supination Supinator (in extended elbow), Biceps (in flexed elbow), brachioradialis*</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Radius, ulna, scaphoid, lunate Ulna is not involved in the formation of the wrist joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During reading osteology, you came across the following bone. Which of the following muscle is not attached to the following bone?", "options": [{"label": "A", "text": "Opponens Pollicis", "correct": false}, {"label": "B", "text": "Adductor pollicis", "correct": true}, {"label": "C", "text": "Abductor pollicis longus", "correct": false}, {"label": "D", "text": "1st palmar interossei.", "correct": false}], "correct_answer": "B. Adductor pollicis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683798459-QTDA104011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Adductor pollicis The marked bone in the given image is the first metacarpal. The muscles attached are opponens pollicis to the radial border and the adjoining palmer surface. First, palmar interossei are attached to the ulnar surface. The abductor pollicis longus is attached on the lateral side. Adductor pollicis is attached to the base of the first phalanx. Hence, the answer to this question will be option B.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Opponens Pollicis Opponens pollicis attached to the radial border and the adjoining palmar surface of the first metacarpal bone. Option: C. Abductor pollicis longus The abductor pollicis longus is attached to the lateral side of the first metacarpal bone. Option: D. 1st palmar interossei. The first palmar interossei are attached to the ulnar surface of the first metacarpal bone.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In the given image, two structures are marked on the following bones, one with a blue arrow(A) and the other with a yellow arrow(B). Which of the following muscles insert onto the following structures?", "options": [{"label": "A", "text": "A- brachialis, B- biceps brachii", "correct": false}, {"label": "B", "text": "A-biceps brachii, B- triceps", "correct": false}, {"label": "C", "text": "A-brachialis, B- triceps", "correct": false}, {"label": "D", "text": "A-biceps brachii, B- brachialis", "correct": true}], "correct_answer": "D. A-biceps brachii, B- brachialis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683798487-QTDA104012IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A-biceps brachii, B- brachialis In the given question, the structure marked with a blue arrow (A) is radial tuberosity. The biceps brachii is inserted on the posterior surface of the radial tuberosity. The structure marked with a yellow arrow (B) is the Ulnar tuberosity to which Brachialis is inserted. Hence the correct answer is Option D.</p>\n<p><strong>Highyeild:</strong></p><p>Radioulnar joints: Movement and muscles involved Movements Muscles involved Pronation Pronator quadratus (strong pronator), pronator teres (Rapid pronator), brachioradialis Supination Supinator (in extended elbow), Biceps (in flexed elbow), brachioradialis*</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. A- brachialis, B- biceps brachii In the given question, the structure marked with a blue arrow (A) is radial tuberosity. The biceps brachii is inserted on the posterior surface of the radial tuberosity. The structure marked with a yellow arrow (B) is the Ulnar tuberosity to which Brachialis is inserted. Option: B. A-biceps brachii, B- triceps In the given question, the structure marked with a blue arrow (A) is radial tuberosity. The biceps brachii is inserted on the posterior surface of the radial tuberosity. Triceps inserts on the Olecranon process of the ulna. The structure marked with a yellow arrow (B) is the Ulnar tuberosity to which Brachialis is inserted. Option: C. A-brachialis, B- triceps In the given question, the structure marked with a blue arrow (A) is radial tuberosity. The biceps brachii is inserted on the posterior surface of the radial tuberosity. Triceps inserts on the Olecranon process of the ulna. The structure marked with a yellow arrow (B) is the Ulnar tuberosity to which Brachialis is inserted.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 22 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "We know in adults, lack of vitamin D gives rise to the disease osteomalacia characterized by progressive softening and bending of the bones. This is due to a defect in the mineralization of the osteoid. Under normal conditions, the osteoid is found along which of the following locations?", "options": [{"label": "A", "text": "The interface between osteocytes and bones", "correct": false}, {"label": "B", "text": "The interface between osteoprogenitor cells and bone marrow", "correct": false}, {"label": "C", "text": "The interface between the fibroblasts in the periosteum", "correct": false}, {"label": "D", "text": "The interface between the osteoblast and bone", "correct": true}], "correct_answer": "D. The interface between the osteoblast and bone", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The interface between the osteoblast and bone Osteoid is the unmineralized organic matrix formed by osteoblasts and found at the interface between these cells and bone.</p>\n<p><strong>Highyeild:</strong></p><p>Intramembranous ossification</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Osteocytes are surrounded by bone and no longer manufacture osteoid. Option: B. Osteoprogenitor cells are similar to stem cells and do not manufacture bone material. Option: C. Fibroblasts are cells of connective tissue forming the periosteum and not bone. Osteoclasts are bone-resorbing cells.</p>\n<p><strong>Extraedge:</strong></p><p>Endochondral ossification</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A child is brought to the emergency department, and his parents complain that he is having depression in his skull. On examination, it was found that the child is having depression at the site of the anterior fontanelle. What could be the cause of this depression?", "options": [{"label": "A", "text": "Decreased Intracranial Pressure", "correct": true}, {"label": "B", "text": "Increased intracranial pressure", "correct": false}, {"label": "C", "text": "Due to rupture of capillaries during delivery", "correct": false}, {"label": "D", "text": "All of the above", "correct": false}], "correct_answer": "A. Decreased Intracranial Pressure", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Decreased Intracranial Pressure Depression in the anterior fontanelle is usually due to Decreased intracranial pressure as mostly found in cases of dehydration. The anterior fontanelle is a diamond-shaped membranous space found at the meeting point of coronal and sagittal sutures. It is usually closed at the age of 18-24 months. It allows the growth of the brain.</p>\n<p><strong>Highyeild:</strong></p><p>The anterior fontanelle ( bregmatic fontanelle , frontal fontanelle ) is the largest fontanelle, and is placed at the junction of the sagittal suture, coronal suture, and frontal suture; it is lozenge-shaped and measures about 4 cm in its anteroposterior and 2.5 cm in its transverse diameter. The fontanelle allows the skull to deform during birth to ease its passage through the birth canal and for expansion of the brain after birth. The anterior fontanelle typically closes between the ages of 12 and 18 months.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect If the anterior fontanelle is bulging, then there is increased intracranial pressure. Increased intracranial pressure found in cases of: Bleeding into brain Brain tumour Infections such as meningitis. Option: C. Incorrect If there is a rupture of capillaries during delivery there is swelling of soft tissue on that part of the skull. This is called as CAPUT SUCCEDANEUM The skull becomes normal within a few days of postnatal life. Option: D. Incorrect As option b and option c given here are not correct in this case.</p>\n<p><strong>Extraedge:</strong></p><p>The anterior fontanelle is useful clinically. Examination of an infant includes palpating the anterior fontanelle. A sunken fontanelle indicates dehydration whereas a very tense or bulging anterior fontanelle indicates raised intracranial pressure. A full anterior fontanelle may also be indicative of neonatal meningitis, specifically acute bacterial meningitis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The police department found a skull without the mandible bone. They delivered the skull to the forensic team for investigation. And the forensic expert told them that this skull belongs to a male. What do you think helped him to confirm the gender of the person?", "options": [{"label": "A", "text": "Well-marked superciliary arches", "correct": true}, {"label": "B", "text": "Well-marked frontal tuber", "correct": false}, {"label": "C", "text": "Presence of the supraorbital notch", "correct": false}, {"label": "D", "text": "Presence of Inion.", "correct": false}], "correct_answer": "A. Well-marked superciliary arches", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Well-marked superciliary arches The Superciliary arch is a rounded curved elevation situated just above the medial part of each orbit. It overlies the frontal sinus and is better marked in males than in females.</p>\n<p><strong>Highyeild:</strong></p><p>The pterion is located in the temporal fossa, approximately 2.6 cm behind and 1.3 cm above the posterolateral margin of the frontozygomatic suture. It is the junction between four bones: the parietal bone. the squamous part of the temporal bone. the greater wing of the sphenoid bone. the frontal bone.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect A frontal tuber or eminence is a low rounded elevation above the superciliary arch one on each side. It is more prominent in females and children. Option: C. Incorrect SUPRAORBITAL NOTCH or foramen is present in both males and females so it cannot be used as a differentiating feature. It is present in the supraorbital margin of the frontal bone, at the junction of the lateral 2/3rd and medial 1/3rd Option: D. Incorrect THE INION IS NOT A DIFFERENTIATING FEATURE AS IT IS PRESENT IN BOTH MALES AND FEMALES. The external occipital protuberance is a median prominence in the lower part of Norma occipitalis. It marks the junction of the head and neck. The most prominent part of this protuberance is called Inion.</p>\n<p><strong>Extraedge:</strong></p><p>The asterion is a visible (craniometric) point on the exposed skull. It is just posterior to the ear. It is the point where three cranial sutures meet: the lambdoid suture. parietomastoid suture. occipitomastoid suture.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient approached you in your clinic and she complained of severe pain in the left mandibular region and numbness in the lower lip and chin region. On examination, it was found that paresthesia in areas extending from the mandibular midline to the left 2nd premolar. You diagnosed it as a case of mental nerve damage. From which foramen mental nerve enters the face?", "options": [{"label": "A", "text": "Supraorbital Foramen", "correct": false}, {"label": "B", "text": "Mental foramen", "correct": true}, {"label": "C", "text": "Infraorbital foramen", "correct": false}, {"label": "D", "text": "Zygomaticofacial foramen", "correct": false}], "correct_answer": "B. Mental foramen", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Mental foramen Mental foramen on the mandible transmits the mental nerves and vessels Damage to the mental nerve leads to paresthesia in areas extending from the mandibular midline to 2nd premolar. The mental nerve is the branch of the inferior alveolar nerve.</p>\n<p><strong>Highyeild:</strong></p><p>The inferior alveolar nerve is a branch of the mandibular nerve. After branching from the mandibular nerve, the inferior alveolar nerve travels behind the lateral pterygoid muscle. It gives off a branch, the mylohyoid nerve, and then enters the mandibular foramen. While in the mandibular canal within the mandible, supplies the lower teeth (molars and second premolar) with sensory branches that form into the inferior dental plexus and give off small gingival and dental nerves to the teeth. Anteriorly, the nerve gives off the mental nerve at about the level of the mandibular 2nd premolars, which exits the mandible via the mental foramen and supplies sensory branches to the chin and lower lip. The inferior alveolar nerve continues anteriorly as the mandibular incisive nerve to innervate the mandibular canines and incisors</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect: The supraorbital foramen transmits the supraorbital nerve and vessels. It is present in the supraorbital margin of the frontal bone at the junction of lateral 2/3rd and medial 1/3rd Option: C. Incorrect Infraorbital foramen transmits infraorbital nerve and vessels The infraorbital foramen is 1 cm below the infraorbital margin, which is formed by zygomatic and maxilla bone. Option: D. Incorrect The zygomaticofacial foramen transmits the zygomaticofacial nerve, a branch of the maxillary nerve. Zygomaticofacial foramen is present in the zygomatic bone.</p>\n<p><strong>Extraedge:</strong></p><p>The Inferior Alveolar nerves supply sensation to the lower teeth, and, via the mental nerve, sensation to the chin and lower lip. The mylohyoid nerve is a motor nerve supplying the mylohyoid and the anterior belly of the digastric.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A young patient is presented in the emergency department. He complains of a severe headache. A few hours before he had a head strike during sports after it he gradually started losing consciousness. The doctor diagnosed it as a case of extradural haemorrhage. What may be the cause of this extradural haemorrhage?", "options": [{"label": "A", "text": "Rupture of the middle meningeal artery at the pterion", "correct": true}, {"label": "B", "text": "Rupture of the sphenopalatine artery in the nasal septum", "correct": false}, {"label": "C", "text": "Rupture of olfactory nerve rootlets", "correct": false}, {"label": "D", "text": "All of the above", "correct": false}], "correct_answer": "A. Rupture of the middle meningeal artery at the pterion", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Rupture of the middle meningeal artery at the pterion The pterion is present in the anterior part of the floor of the temporal fossa, it is a H shaped suture where four bones adjoin each other: 1-frontal2-parietal3-temporal4 -greater wing of the sphenoid The anterior division of the middle meningeal artery is present closely over the bone at the site of the pterion and it may be ruptured there leading to clot formation between the skull bone and dura mater[extradural haemorrhage].</p>\n<p><strong>Highyeild:</strong></p><p>The pterion is known as the weakest part of the skull . The anterior division of the middle meningeal artery runs underneath the pterion. Consequently, a traumatic blow to the pterion may rupture the middle meningeal artery causing an epidural haematoma. The pterion may also be fractured indirectly by blows to the top or back of the head that place sufficient force on the skull to fracture the pterion. Pterion</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect The sphenopalatine artery is the main artery that supplies the nasal septum area[ posterosuperior part] Damage to this artery leads to epistaxis [ bleeding from the nose] The sphenopalatine artery is the artery for epistaxis. Option: C. Incorrect Haemorrhage means the escape of blood from ruptured blood vessels either inside or outside the body. Hemorrhagic condition only arises when rupture of capillaries or blood vessels occurs, it is not found in the cases of nerve damage. Rupture of the cribriform plate of ethmoid leads to, Anosmia [loss of smell sensation] as the olfactory nerve rootlets are damaged in this case. rhinorrhea [CSF LEAKAGE THROUGH NOSE], as the cribriform plate separates the anterior cranial fossa from the nasal cavity. So if it is damaged the CSF flows out into the nasal cavity Option: D. Incorrect Because Options B and C are Incorrect, so all of the above cannot be the correct answer.</p>\n<p><strong>Extraedge:</strong></p><p>The pterion is a structural landmark for a neurosurgical approach to middle cerebral artery aneurysms.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient is having unilateral palsy of facial expression and abnormal blink reflex. On examination, it was found that the temporal bone is fractured. Diagnosis of infratemporal injury of the facial nerve is made by the doctor. From which foramen facial nerve enters the face region?", "options": [{"label": "A", "text": "Stylomastoid Foramen", "correct": true}, {"label": "B", "text": "Jugular foramen", "correct": false}, {"label": "C", "text": "Foramen ovale", "correct": false}, {"label": "D", "text": "Carotid canal", "correct": false}], "correct_answer": "A. Stylomastoid Foramen", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Stylomastoid Foramen The stylomastoid foramen transmits the facial nerve and the stylomastoid branch of the posterior auricular artery. The stylomastoid foramen is present posterior to the root of the styloid process, at the anterior end of the mastoid process.</p>\n<p><strong>Highyeild:</strong></p><p>The stylomastoid foramen is between the styloid and mastoid processes of the temporal bone. The average distance between the opening of the stylomastoid foramen and the styloid process is around 0.7 mm or 0.8 mm in adults but may decrease to around 0.2 mm during agei The stylomastoid foramen transmits the facial nerve and the stylomastoid artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect The jugular foramen is present in the posterior part of norma basalis, in between the occipital and petrous part temporal bone. It transmits the inferior petrosal sinus 2-meningeal branch of ascending pharyngeal artery 3-internal jugular vein 4-middle part;9 th ;10 th and 11 th cranial nerve Option: C. Incorrect Foramen ovale is large and ovale in shape.it is present posterolateral to the upper end of the posterior border of the lateral pterygoid plate 1-it transmits- mandibular nerve 2-accessory meningeal artery 3-lesser petrosal nerve 4-emissary vein connecting cavernous sinus to pterygoid plexus of vein Option: D. Incorrect The Carotid canal is the passageway in the temporal bone through which the internal carotid artery enters the middle cranial fossa from the neck along with the venous and sympathetic plexus. The canal starts on the inferior surface of the temporal bone at the external opening of the carotid canal [carotid foramen]</p>\n<p><strong>Extraedge:</strong></p><p>Bell's palsy can result from inflammation of the facial nerve where it leaves the skull at the stylomastoid foramen. Patients with Bell's palsy appear with facial drooping on the affected side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient is having a head injury on the front side of the face region in which the frontal bone and the cribriform plate are fractured [injury of anterior cranial fossa].which of the given symptoms do you expect to find in the patient?", "options": [{"label": "A", "text": "Palsy of muscles of facial expression", "correct": false}, {"label": "B", "text": "Loss of motor activity of muscles of mastication", "correct": false}, {"label": "C", "text": "Deviation of the tongue to one side", "correct": false}, {"label": "D", "text": "Rhinorrhoea", "correct": true}], "correct_answer": "D. Rhinorrhoea", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Rhinorrhoea The relation of the nose to the anterior cranial fossa is through the cribriform plate so fracture of the cribriform plate of ethmoid with tearing off meninges may tear the olfactory nerve rootlet in such cases CSF drip out from the nasal cavity [rhinorrhea].</p>\n<p><strong>Highyeild:</strong></p><p>The specialized olfactory receptor neurons of the olfactory nerve are located in the olfactory mucosa of the upper parts of the nasal cavity. The olfactory nerves consist of a collection of many sensory nerve fibres that extend from the olfactory epithelium to the olfactory bulb, passing through the many openings of the cribriform plate, a sieve-like structure of the ethmoid bone .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect Palsy of muscles of facial expression can result from the damage to the facial nerve which supplies these muscles. The facial nerve enters the face region through the stylomastoid foramen present at the anterior end of the mastoid notch. So it is less likely to get damaged in injury to the front of the face region. Option: B. Incorrect Loss of motor activity of muscles of mastication can occur due to injury to the mandibular branch of the trigeminal nerve. And mandibular nerve is transmitted through the foramen ovale present at the posterior border of the lateral pterygoid plate Option: C. Incorrect Deviation of the tongue to one side is found in cases of hypoglossal nerve injury Hypoglossal nerve is transmitted by the hypoglossal or anterior condylar canal, it is seen in the posterior part of norma basalis and it pierces the bone anterior superior to the occipital condyle.</p>\n<p><strong>Extraedge:</strong></p><p>The olfactory nerve is the shortest of the twelve cranial nerves and, similar to the optic nerve, does not emanate from the brainstem .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient is presented to you having a deviation of the tongue towards the left side . But he is able to accurately judge the taste of the food provided. You diagnosed it as a case of hypoglossal nerve injury. From which foramen does this nerve leave the skull?", "options": [{"label": "A", "text": "Anterior Condylar Canal", "correct": true}, {"label": "B", "text": "Jugular foramen", "correct": false}, {"label": "C", "text": "Stylomastoid foramen", "correct": false}, {"label": "D", "text": "Carotid canal", "correct": false}], "correct_answer": "A. Anterior Condylar Canal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior Condylar Canal The hypoglossal canal or anterior condylar canal present in the posterior part of norma basalis pierces the bone anterior superior to the occipital condyle and is directed laterally and slightly forwards. It transmits the hypoglossal nerve . This canal is located posterior to the jugular foramen.</p>\n<p><strong>Highyeild:</strong></p><p>The hypoglossal nerve, also known as the twelfth cranial nerve, cranial nerve XII, or simply CN XII, is a cranial nerve that innervates all the extrinsic and intrinsic muscles of the tongue except for the palatoglossus, which is innervated by the vagus nerve. The hypoglossal nerve is of a general somatic efferent (GSE) type. CN XII is a nerve with a solely motor function. The nerve arises from the hypoglossal nucleus in the medulla as a number of small rootlets pass through the hypoglossal canal and down through the neck, and eventually passes up again over the tongue muscles it supplies into the tongue.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect JUGULAR FORAMEN IS PLACED IN THE POSTERIOR END OF PETRO OCCIPITAL SUTUR INTERNAL JUGULAR VEIN MENINGEAL BRANCH OF OCCIPITAL ARTERY Option: C. Incorrect The stylomastoid foramen is situated posterior to the root of the styloid process, at the anterior end of the mastoid notch It transmits the facial nerve and stylomastoid branch of a posterior auricular artery Option: D. Incorrect The Carotid canal transmits the internal carotid artery; venous and sympathetic plexus around it The Carotid canal is present in the temporal bone</p>\n<p><strong>Extraedge:</strong></p><p>Damage to the hypoglossal nucleus will lead to the wasting of muscles of the tongue and deviation towards the affected side when it is stuck out. This is because of the weaker genioglossal muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient arrived in the emergency department with a severe head injury and profuse bleeding from the head region. On examination bleeding and discharge of CSF were found from the external acoustic meatus region. After 4 hours, the patient complained of hearing impairment also. But the other sensations like the olfaction of the patient are found to be normal. What do you think is the cause of otorrhea in this case?", "options": [{"label": "A", "text": "Fracture of the temporal bone and disruption of the tympanic membrane", "correct": true}, {"label": "B", "text": "Fracture of the cribriform plate", "correct": false}, {"label": "C", "text": "Fracture of the zygomatic bone", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Fracture of the temporal bone and disruption of the tympanic membrane", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fracture of the temporal bone and disruption of the tympanic membrane CSF otorrhea is a condition in which the spinal fluid drains through the ear. Patients with CSF otorrhea often have hearing loss in the affected ear as the tympanic membrane is damaged. Fractures of the temporal bone accompanied by dural tears are the commonest cause of cerebrospinal otorrhea. Usually, the tympanic membrane is also ruptured in these cases.</p>\n<p><strong>Highyeild:</strong></p><p>The vestibulocochlear nerve or auditory vestibular nerve, also known as the eighth cranial nerve, cranial nerve VIII, is a cranial nerve that transmits sound and equilibrium (balance) information from the inner ear to the brain. Through olivocochlear fibres, it also transmits motor and modulatory information from the superior olivary complex in the brainstem to the cochlea.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect As if the cribriform plate of the ethmoid bone is ruptured that leading to bleeding and discharge of CSF through the nasal cavity And the patient will be having anosmia [loss of smell sensation] as the olfactory nerve rootlets pass through the cribriform plate, and in this patient, the olfactory sense is found normal. So the cribriform plate is not ruptured in this case. Option: C. Incorrect As if the ZYGOMATIC BONE IS DAMAGED that leads to 1-flatness of the cheek 2-Altered sensations underneath the eye on the affected side 3- Pain with jaw movements BUT FRACTURE OF ZYGOMATIC BONE would not lead to CSF leakage through the ear, as found in this patient. Otorrhea is only found in cases of injury to the middle cranial fossa, and the zygomatic bone is not related to the middle cranial fossa.</p>\n<p><strong>Extraedge:</strong></p><p>The vestibulocochlear nerve is derived from the embryonic otic placode.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Suppose a patient is presented to you in your clinic with a fracture of the spine or sphenoid bone. All of the given symptoms are likely to be found in the patient with a fractured spine or sphenoid except.", "options": [{"label": "A", "text": "Loss of secretion of sublingual salivary gland", "correct": false}, {"label": "B", "text": "Loss of secretion of the parotid gland", "correct": false}, {"label": "C", "text": "Loss of secretion of the submandibular gland", "correct": false}, {"label": "D", "text": "Loss of taste sensation from posterior 1/3rd of tongue", "correct": true}], "correct_answer": "D. Loss of taste sensation from posterior 1/3rd of tongue", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Loss of taste sensation from posterior 1/3rd of tongue The glossopharyngeal nerve carries the taste sensation from the posterior part of the tongue. Injury to the glossopharyngeal nerve can lead to loss of taste sensation from the posterior 1/3rd of the tongue. The glossopharyngeal nerve leaves the skull through the jugular foramen placed at the posterior end of the petro occipital suture. It is not present in relation to the spine of the sphenoid so not affected by fracture of the spine of the</p>\n<p><strong>Highyeild:</strong></p><p>The glossopharyngeal nerve , also known as the ninth cranial nerve, cranial nerve IX, or simply CN IX, is a cranial nerve that exits the brainstem from the sides of the upper medulla, just anterior (closer to the nose) to the vagus nerve. Being a mixed nerve (sensorimotor), it carries afferent sensory and efferent motor information. The motor division of the glossopharyngeal nerve is derived from the basal plate of the embryonic medulla oblongata, whereas the sensory division originates from the cranial neural crest .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. Incorrect The chorda tympani nerve supplying secretomotor fibres to the sublingual salivary gland lies Medial to the Spine of the So it is usually damaged in fractures of the spine of sphenoid Option: B. Incorrect As the auriculotemporal nerve supplies secretomotor fibres to the parotid gland and is related to the lateral aspect of the spine of the sphenoid so if the spine of the sphenoid is fractured it is also likely to be damaged, that leads to loss of secretion of the parotid gland Option: C. Incorrect As the chorda tympani nerve also supplies the secretomotor fibres to the submandibular gland, and it is related medially to the spine of sphenoid bone so injury to this nerve due to fracture of the spine of sphenoid would lead to loss of secretion from both sublingual and submandibular salivary gland.</p>\n<p><strong>Extraedge:</strong></p><p>The glossopharyngeal nerve has five distinct general functions: Branchial motor (special visceral efferent) – supplies the stylopharyngeus muscle. Visceral motor (general visceral efferent) – provides parasympathetic innervation of the parotid gland via the otic ganglion Visceral sensory (general visceral afferent) – carries visceral sensory information from the carotid sinus and carotid body. General sensory (general somatic afferent) – provides general sensory information from the inner surface of the tympanic membrane, upper pharynx (GVA), and the posterior one-third of the tongue. Visceral afferent (special visceral afferent) – provides taste sensation from the posterior one-third of the tongue, including circumvallate papillae.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient arrived at your clinic and he has a complaint of loss of all sensations from the anterior 2/3rd of the tongue. But he is having sensations from the posterior 1/3rd of the tongue. On asking he told that he has undergone an extraction of a misplaced wisdom tooth last month and after it these problems arose. What could be the possible cause for this loss of sensation in this case?", "options": [{"label": "A", "text": "Damage to the lingual nerve during extraction of wisdom tooth", "correct": true}, {"label": "B", "text": "Damage to the glossopharyngeal nerve", "correct": false}, {"label": "C", "text": "Damage to the facial nerve", "correct": false}, {"label": "D", "text": "Damage to the middle meningeal artery at the pterion", "correct": false}], "correct_answer": "A. Damage to the lingual nerve during extraction of wisdom tooth", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The lingual nerve is a branch of the posterior branch of the mandibular nerve it is sensory to the anterior 2/3rd of the tongue and floor of the mouth and it is in contact with the mandible medial to 3rd molar tooth. So it is commonly damaged in cases of extraction of wisdom teeth leading to sensory loss over that area of supply.</p>\n<p><strong>Highyeild:</strong></p><p>The trigeminal nerve, also known as the fifth cranial nerve, cranial nerve V, is a cranial nerve responsible for sensation in the face and motor functions such as biting and chewing; it is the most complex of the cranial nerves. The motor division of the trigeminal nerve derives from the basal plate of the embryonic pons, and the sensory division originates in the cranial neural crest.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect The glossopharyngeal nerve is sensory to the posterior 1/3 rd of the tongue It leaves the skull through the jugular foramen that is present posterior end petro occipital suture It is not damaged in cases of tooth extraction Option: C. Incorrect The facial nerve enters the face region from the skull through the stylomastoid foramen present posterior to the root of the styloid process Facial nerve supplies the muscles for facial expression if it is damaged that lead to abnormal facial expressions, and it is not present in this case so facial nerve is not involved in this case. Option: D. Incorrect The pterion site is present in the temporal fossa as an h-shaped suture where 4 bones meet-frontal parietal temporal greater wing of the sphenoid The anterior division of the middle meningeal artery is closely related to the pterion and ruptured in cases of roadside accidents that lead to extradural haemorrhage Damage to the artery will never lead to loss of sensations, as it is the function of nerves, not the</p>\n<p><strong>Extraedge:</strong></p><p>The sensory function of the trigeminal nerve is to provide tactile, proprioceptive, and nociceptive afferents to the face and mouth. Its motor function activates the muscles of mastication, the tensor tympani, tensor veli palatini, mylohyoid and the anterior belly of the digastric. The trigeminal nerve carries general somatic afferent fibres (GSA), which innervate the skin of the face via ophthalmic (V1), maxillary (V2) and mandibular (V3) divisions. The trigeminal nerve also carries special visceral efferent (SVE) axons, which innervate the muscles of mastication via the mandibular (V3) division.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A person is found hanging with a rope in his room, the people present there at the moment quickly take him down and shift him to the hospital. The doctor on examination of the patient declared him dead. What do you think should be the most important reason for sudden death in cases of hanging?", "options": [{"label": "A", "text": "The fracture of the odontoid process usually compresses the vital centres in the medulla", "correct": true}, {"label": "B", "text": "Fracture of bones around intervertebral foramina of cervical vertebrae", "correct": false}, {"label": "C", "text": "Damage to the anterior spinal artery", "correct": false}, {"label": "D", "text": "Damage to the posterior spinal artery", "correct": false}], "correct_answer": "A. The fracture of the odontoid process usually compresses the vital centres in the medulla", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The fracture of the odontoid process usually compresses the vital centres in the medulla In cases of hanging, the rope puts a lot of pressure over the neck region that leads to fracture of the odontoid process of axis vertebrae and breaking of the odontoid process usually hits upon the vital centre of the medulla oblongata that leads to the sudden death of the person.</p>\n<p><strong>Highyeild:</strong></p><p>The atlantooccipital joint allows the head to nod up and down on the vertebral column. The dens act as a pivot that allows the atlas and attached head to rotate on the axis, side to side. The atlas's chief peculiarity is that it has no body. It is ring-like and consists of an anterior and a posterior arch and two lateral masses. The atlas and axis are important neurologically because the brainstem extends down to the axis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect Fractures of bones near the intervertebral foramina of the cervical region usually press the anteriorly placed spinal nerve that causes pain along the course and distribution of these nerves Option: C. Incorrect Damage to the anterior spinal artery leads to ischemia of the anterior 2/3 rd of the spinal cord resulting in loss of function of the anterior 2/3 rd of spinal cord affecting descending corticospinal tract and ascending spinothalamic tract loss of motor function and pain and temperature sensation is the result found in the patient Option: D. Incorrect The posterior spinal artery supplies posterior 1/3 rd of spinal cord damage to it leads to loss of proprioception and vibratory sensations of the same side The dens, also called the odontoid process or the peg, is the most pronounced projecting feature of the axis.</p>\n<p><strong>Extraedge:</strong></p><p>The dens exhibit a slight constriction where it joins the main body of the vertebra. The condition where the dens are separated from the body of the axis is called os odontoideum and may cause nerve and circulation compression syndrome. Hangman's fracture is the colloquial name given to a fracture of both pedicles, of the axis vertebra (C2).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient arrives at your clinic and you have to take the carotid pulse of the patient as your senior doctor told you to do so, at which place do you look for the carotid pulse?", "options": [{"label": "A", "text": "At the C6 vertebral level", "correct": true}, {"label": "B", "text": "At the wrist of the patient on the radial side", "correct": false}, {"label": "C", "text": "In the cubital fossa", "correct": false}, {"label": "D", "text": "In the popliteal fossa", "correct": false}], "correct_answer": "A. At the C6 vertebral level", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>At the C6 vertebral level A carotid pulse is a pressure signal acquired over the carotid artery as it passes near the surface of the body at the neck. The anterior tubercle of the sixth cervical vertebrae is large and is called the carotid tubercle (Chassaignac tubercle) because the common carotid artery can be compressed against it.</p>\n<p><strong>Highyeild:</strong></p><p>The costal element of the seventh cervical vertebra may get enlarged to form a cervical rib. A cervical rib is an additional rib arising from the C7 vertebra and usually gets attached to the 1st rib near the insertion of the scalenus anterior. If the rib is more than 5 cm long, it usually displaces the brachial plexus and the subclavian artery upwards.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect A Radial pulse is usually taken on the wrist area between the wrist bone and the tendon on the thumb side of your wrist. By applying enough pressure over the lateral area of the wrist radial artery pulsations are felt not carotid artery pulsations Option: C. Incorrect The brachial artery pulsations [brachial pulse] are felt usually by feeling the biceps tendon in the area of the cubital fossa about 2-3 cm above it cubital fossa is an inverted triangular space that forms the transition between the arm and forearm, it is located anterior to the elbow joint Option: D. Incorrect Popliteal pulse is detected in the portion of the leg behind the knee [in the popliteal fossa] The pulse here is from the blood flow to the popliteal artery, the vital blood supply to the lower limb</p>\n<p><strong>Extraedge:</strong></p><p>The joints in the lateral parts of adjacent bodies of cervical vertebrae are called Luschka’s joints. The osteophytes commonly occur in these joints. The cervical nerve roots lying posterolateral to these joints may get pressed causing pain along their distribution.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient is being diagnosed with osteophytes of Luschka’s joint. And due to this, he is having a distortion of the vertebral artery leading to vertebrobasilar insufficiency, vertigo and dizziness. From which foramen does the vertebral artery pass?", "options": [{"label": "A", "text": "Foramen Transversarium", "correct": true}, {"label": "B", "text": "Intervertebral foramina", "correct": false}, {"label": "C", "text": "Vertebral foramen", "correct": false}, {"label": "D", "text": "None of the above", "correct": false}], "correct_answer": "A. Foramen Transversarium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Foramen Transversarium The vertebral artery courses through the foramen transversarium and lie lateral to Luschka's joint. So osteophytes of the Luschka joint distort vertebral arteries leading to vertigo, dizziness and vertebrobasilar insufficiency.</p>\n<p><strong>Highyeild:</strong></p><p>Kyphosis Kyphosis is an abnormal curvature of the vertebral column in the thoracic region, producing a \"hunchback\" deformity. This condition occurs in certain disease states, the most dramatic of which is usually secondary to tuberculosis infection of a thoracic vertebral body, where the kyphosis becomes angulated at the site of the lesion. This produces the gibbous deformity, a deformity that was prevalent before the use of anti-tuberculosis medication.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. Incorrect Intervertebral foramina contain - The root of the spinal nerve Spinal artery Communicating veins between internal and external plexuses So damage to intervertebral foramina will not affect the vertebral artery Option: C. Incorrect The vertebral foramen houses the spinal cord and its meninges This large tunnel running up and down inside all the vertebrae contains the spinal cord and is called the spinal canal</p>\n<p><strong>Extraedge:</strong></p><p>Lordosis Lordosis is an abnormal curvature of the vertebral column in the lumbar region, producing a swayback deformity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The Vomer-Sphenoid rostrum junction is?", "options": [{"label": "A", "text": "Syndesmosis", "correct": false}, {"label": "B", "text": "Synostosis", "correct": false}, {"label": "C", "text": "Schindylesis", "correct": true}, {"label": "D", "text": "Gomphosis", "correct": false}], "correct_answer": "C. Schindylesis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Schindylesis A schindylesis is a specialized suture in which a ridged bone fits into a groove on a neighbouring element, e.g. where the cleft between the alae of the vomer receives the rostrum of the sphenoid.</p>\n<p><strong>Highyeild:</strong></p><p>Schindylesis is an articulation in which two bones are joined by fitting the ridge of one bone into the groove of another. Also known as a \"wedge-and-groove\" joint, This fibrous suture joint can be found between the vomer and the perpendicular plate of the ethmoid bone as well as between the vomer and the gap between the maxilla and palatine. Schindylesis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Syndesmosis A syndesmosis is defined as a fibrous joint in which two adjacent bones are linked by a strong membrane or ligaments. Option:B. Synostosis Synostosis (plural: synostoses) is the fusion of two or more bones. It can be normal in puberty, fusion of the epiphyseal plate to become the epiphyseal line. Option:D. Gomphosis A gomphosis is a fibrous mobile peg-and-socket joint. The roots of the teeth (the pegs) fit into their sockets in the mandible and maxilla and are the only examples of this type of joint.</p>\n<p><strong>Extraedge:</strong></p><p>The distal tibiofibular syndesmosis/inferior tibiofibular joint is a syndesmotic joint. It is formed between the distal tibia(concave surface) and fibula(convex surface), with no articular capsule or synovial membrane as a fibrous joint, and attached by the interosseous ligament (IOL), the anterior-inferior tibiofibular ligament (AITFL), the posterior-inferior tibiofibular ligament (PITFL), and the transverse tibiofibular ligament (TTFL).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following bones do not contribute to the nasal septum?", "options": [{"label": "A", "text": "Sphenoid", "correct": false}, {"label": "B", "text": "Lacrimal", "correct": true}, {"label": "C", "text": "Palatine", "correct": false}, {"label": "D", "text": "Ethmoid", "correct": false}], "correct_answer": "B. Lacrimal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lacrimal NASAL SEPTUM The nasal septum is a median osseocartilaginous partition between the two halves of the nasal cavity. On each side, it is covered by a mucous membrane and forms the medial wall of both nasal cavities. Lacrimal bones do not contribute to the formation of nasal septum.</p>\n<p><strong>Highyeild:</strong></p><p>The bony part is formed almost entirely by: A. The vomer B. The perpendicular plate of ethmoids. However, its margins receive contributions from the nasal spine of the frontal bone, the rostrum of the sphenoid, and the nasal crests of the nasal, palatine and maxillary bones. The cartilaginous part is formed by: A. The septal cartilage B. The septal processes of the inferior nasal cartilages Nasal septum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- A. Sphenoid B. Palatine C. Ethmoid All the bones mentioned in the options are contributing to the formation of the nasal septum.</p>\n<p><strong>Extraedge:</strong></p><p>The lowest part of the septum is a narrow strip of bone that projects from the maxilla and the palatine bones and is the length of the septum. This strip of bone is called the maxillary crest; it articulates in front with the septal nasal cartilage and at the back with the vomer. The maxillary crest is described in the anatomy of the nasal septum as having a maxillary component and a palatine component.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Uncinate process of ethmoid bone attached anteriorly to which bone:", "options": [{"label": "A", "text": "Sphenoid", "correct": false}, {"label": "B", "text": "Ethmoid", "correct": false}, {"label": "C", "text": "Frontal", "correct": false}, {"label": "D", "text": "Lacrimal bone", "correct": true}], "correct_answer": "D. Lacrimal bone", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lacrimal bone The uncinate process of ethmoid bone anteriorly articulates with lacrimal bone and posteriorly with inferior turbinate.</p>\n<p><strong>Highyeild:</strong></p><p>Lateral wall of the nose The skeleton of the lateral wall is partly bony, partly cartilaginous, and partly made up only of soft tissues. The bony part is formed from before backwards by the following bones: Nasal Frontal process of the maxilla Lacrimal Labyrinth of ethmoid with superior and middle conchae Inferior nasal concha made up of spongy bone only Perpendicular plate of palatine bone together with its orbital and sphenoidal processes Medial pterygoid plate. The cartilaginous part is formed by: a. The superior nasal cartilage. b. The inferior nasal cartilage. c. 3 or 4 small cartilages of the ala. Lateral wall of the nose</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options A, B and C are incorrect answers because the Uncinate process of ethmoid bone anteriorly articulates with lacrimal bone and posteriorly with inferior turbinate.</p>\n<p><strong>Extraedge:</strong></p><p>The inferior meatus lies underneath the inferior concha and is the largest of the three meatuses. The nasolacrimal duct opens into it at the junction of its anterior one-third and posterior two-thirds. The opening is guarded by the lacrimal fold, or Hasner’s valve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True statement about orbital articulation is:", "options": [{"label": "A", "text": "Medial wall of the orbit is formed by the maxilla, sphenoid, ethmoid and the lacrimal bone", "correct": true}, {"label": "B", "text": "Floor formed by maxilla, zygomatic and ethmoid", "correct": false}, {"label": "C", "text": "Lateral wall of the orbit is formed by the frontal bone, zygomatic bone, and greater wing of the sphenoid", "correct": false}, {"label": "D", "text": "Inferior orbit tissue is formed between the medial wall and the floor of the orbit", "correct": false}], "correct_answer": "A. Medial wall of the orbit is formed by the maxilla, sphenoid, ethmoid and the lacrimal bone", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Medial wall of the orbit is formed by the maxilla, sphenoid, ethmoid and the lacrimal bone</p>\n<p><strong>Highyeild:</strong></p><p>The borders and anatomical relations of the bony orbit are as follows: Roof (superior wall) – Formed by the frontal bone and the lesser wing of the sphenoid. The frontal bone separates the orbit from the anterior cranial fossa. Floor (inferior wall) – Formed by the maxilla, palatine and zygomatic bones. The maxilla separates the orbit from the underlying maxillary sinus. Medial wall – Formed by the ethmoid, maxilla, lacrimal and sphenoid bones. The ethmoid bone separates the orbit from the ethmoid sinus. Lateral wall – Formed by the zygomatic bone and greater wing of the sphenoid. Apex – Located at the opening to the optic canal, the optic foramen. Base – Opens out into the face, and is bounded by the eyelids. It is also known as the orbital rim. Orbit boundaries</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:B. The floor formed by the maxilla, zygomatic and ethmoid The floor (inferior wall) of the orbit is formed by the maxilla, palatine and zygomatic bones. The maxilla separates the orbit from the underlying maxillary sinus. Option:C. Lateral wall of the orbit is formed by the frontal bone, zygomatic bone, and greater wing of the sphenoid The lateral wall of the orbit is formed by the zygomatic bone and the greater wing of the sphenoid Option:D. Inferior orbit tissue is formed between the medial wall and the floor of the The floor (inferior wall) is formed by the maxilla, palatine and zygomatic bones. The maxilla separates the orbit from the underlying maxillary sinus.</p>\n<p><strong>Extraedge:</strong></p><p>The bony orbit contains the eyeballs and their associated structures: Extraocular muscles – These muscles are separate from the eye. They are responsible for the movement of the eyeball and superior eyelid. Eyelids – These cover the orbits anteriorly. Nerves: Several cranial nerves supply the eye and its structures; optic, oculomotor, trochlear, trigeminal and abducens nerves. Blood vessels: The eye receives blood primarily from the ophthalmic artery. Venous drainage is via the superior and inferior ophthalmic veins.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Choose the incorrect option regarding marked structures in the given image:", "options": [{"label": "A", "text": "A- Origin of the superior constrictor", "correct": false}, {"label": "B", "text": "B- Origin of Tensor Veli Palatini", "correct": false}, {"label": "C", "text": "C- Origin of the medial pterygoid", "correct": false}, {"label": "D", "text": "D- Origin of Tensor tympani", "correct": true}], "correct_answer": "D. D- Origin of Tensor tympani", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681434222-QTDA028019IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>D- Origin of Tensor tympani All the Options can be explained by the following image, here only Option D is an incorrect statement</p>\n<p><strong>Highyeild:</strong></p><p>The pterygoid hamulus is a hook-like process at the lower extremity of the medial pterygoid plate of the sphenoid bone of the skull. It is the superior origin of the pterygomandibular raphe and the levator veli palatini muscle.</p>\n<p><strong>Extraedge:</strong></p><p>' In the pterygoid processes of the sphenoid, above the pterygoid fossa is a small, oval, shallow depression, the scaphoid fossa , which gives origin to the Tensor veli palatini. It is not the same as and has to be distinguished from the scaphoid fossa of the external ear or pinna.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Maxilla bone does not articulate with:", "options": [{"label": "A", "text": "Nasal", "correct": false}, {"label": "B", "text": "Sphenoid", "correct": true}, {"label": "C", "text": "Lacrimal", "correct": false}, {"label": "D", "text": "Frontal", "correct": false}], "correct_answer": "B. Sphenoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sphenoid Maxilla bone articulates with the following bones: Frontal Ethmoid Lacrimal Nasal Zygomatic Inferior Nasal Concha Palatine Vomer Adjacent Fused Maxilla. Bones of Skull as seen from the frontal aspect</p>\n<p><strong>Highyeild:</strong></p><p>Periodontal disease is a common cause of bone resorption within the alveolar process of the maxilla bone which may result after a severe inflammation of the gums (gingivitis). Children, older people and people with poor oral hygiene are particularly affected. Certain bacteria or immunosuppression may also contribute to the progress of this disease. Another cause for alveolar ridge resorption can be an aplastic tooth or missing tooth (e.g. after extraction)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options A. Nasal, C. Lacrimal and D. Frontal bones all articulate with maxilla bone.</p>\n<p><strong>Extraedge:</strong></p><p>As the maxilla is the central bone of the midface it can fracture through various accidents, most commonly the Le Fort fractures which are subclassified into three types: Le Fort I fracture: detachment of the alveolar process from the maxilla in a rectangular form, with the centre being at the inferior border of the bony nasal cavity. This leaves the patient with a mobile jaw. Le Fort II fracture: pyramidal in shape, involving the alveolar process, midface and nasal bones. The midface is mobile Le Fort III fracture: separation of the viscerocranium from the neurocranium . The entire maxilla and nasal bones detach from the skull, leaving the face in its entirety to hang at the discretion of the facial tissues.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Sphenopalatine foramen opens into which wall of pterygopalatine fossa:", "options": [{"label": "A", "text": "Medial", "correct": true}, {"label": "B", "text": "Lateral", "correct": false}, {"label": "C", "text": "Superior", "correct": false}, {"label": "D", "text": "Inferior", "correct": false}], "correct_answer": "A. Medial", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Medial The sphenopalatine foramen opens into the medial wall of the pterygopalatine fossa. Sphenopalatine foramen Communicating with the medial wall of the pterygopalatine fossa.</p>\n<p><strong>Highyeild:</strong></p><p>PTERYGOPALATINE FOSSA BOUNDARIES Anterior: Superomedial part of the posterior surface of the maxilla. Posterior : Root of the pterygoid process and adjoining part of the anterior surface of the greater wing of the sphenoid. Medial : Upper part of the perpendicular plate of the palatine bone. The orbital and sphenoidal processes of the bone also take part. Lateral : The fossa opens into the infratemporal fossa through the pterygomaxillary fissure. Superior: Undersurface of the body of the Inferior : Closed by the pyramidal process of the palatine bone in the angle between the maxilla and the pterygoid proce.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B, C & D all are incorrect answers because the Sphenopalatine foramen opens into the medial wall of the pterygopalatine fossa.</p>\n<p><strong>Extraedge:</strong></p><p>Communications of Pterygopalatine fossa Anteriorly: With the orbit through the medial end of the inferior orbital fissure. Posteriorly: 1. Middle cranial fossa through the foramen rotundum. 2. Foramen lacerum through the pterygoid canal. 3. Pharynx through the palatinovaginal canal. Medially: With the nose through the sphenopalatine foramen. Laterally: With the infratemporal fossa through the pterygomaxillary fissure. Inferiorly: With the oral cavity through the greater and lesser palatine canals.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following cranial nerves are seen in the posterior cranial fossa:", "options": [{"label": "A", "text": "3 to 12", "correct": true}, {"label": "B", "text": "4 to 12", "correct": false}, {"label": "C", "text": "5 to 12", "correct": false}, {"label": "D", "text": "6 to 12", "correct": false}], "correct_answer": "A. 3 to 12", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>3 to 12 Cranial nerves I and II don’t arise from the brain stem. The r est of the cranial nerves arise from the brain stem, so they pass through the posterior cranial fossa</p>\n<p><strong>Highyeild:</strong></p><p>Cranial nerve found in pons - V Cranial nerves attached to midbrain -III and IV Cranial nerves found at the junction between pons and medulla - VI,VII,VIII Cranial nerves attached to medulla - IX, X, XI, XII Cranial nerves location seen in the inferior surface of the brain</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. 4 to 12, option C. 5 to 12, and option D. 6 to 12 are the incorrect answer because Cranial nerves I and II don’t arise from the brain stem, Rest of the cranial nerves III to XII arise from the brain stem, so they pass through the posterior cranial fossa.</p>\n<p><strong>Extraedge:</strong></p><p>The thirteenth cranial nerve , commonly referred to as the nervus terminalis or terminal nerve, is a highly conserved multifaceted nerve found just above the olfactory bulbs in humans and most vertebrate species . In most forms its fibers course from the rostral portion of the brain to the olfactory and nasal epithelia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The structure passing through the marked foramen:", "options": [{"label": "A", "text": "Inferior Alveolar Nerve", "correct": true}, {"label": "B", "text": "Lingual nerve", "correct": false}, {"label": "C", "text": "Maxillary nerve", "correct": false}, {"label": "D", "text": "Facial", "correct": false}], "correct_answer": "A. Inferior Alveolar Nerve", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681434249-QTDA028023IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior Alveolar Nerve Marked foramen is mandibular foramen Mandibular foramen transmits inferior alveolar nerve and vessels.</p>\n<p><strong>Highyeild:</strong></p><p>The inferior alveolar nerve is a branch of the mandibular nerve. After branching from the mandibular nerve, the inferior alveolar nerve travels behind the lateral pterygoid muscle. It gives off a branch, the mylohyoid nerve, and then enters the mandibular foramen. While in the mandibular canal within the mandible, supplies the lower teeth (molars and second premolar) with sensory branches that form into the inferior dental plexus and give off small gingival and dental nerves to the teeth. Anteriorly, the nerve gives off the mental nerve at about the level of the mandibular 2nd premolars, which exits the mandible via the mental foramen and supplies sensory branches to the chin and lower lip. The inferior alveolar nerve continues anteriorly as the mandibular incisive nerve to innervate the mandibular canines and incisors</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:B. Lingual nerve The lingual nerve is often in a common stem with the inferior alveolar nerve after the mandibular division enters the infratemporal fossa through the foramen ovale. OptionC. Maxillary nerve It runs inferior and lateral to the ophthalmic nerve. It then leaves the middle cranial fossa through the foramen rotundum and enters the superior part of the pterygopalatine fossa. Option:D. Facial The stylomastoid foramen transmits the facial nerve and the stylomastoid artery.</p>\n<p><strong>Extraedge:</strong></p><p>The Inferior Alveolar nerves supply sensation to the lower teeth, and, via the mental nerve, sensation to the chin and lower lip. The mylohyoid nerve is a motor nerve supplying the mylohyoid and the anterior belly of the digastric.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which joint helps to look left and right:", "options": [{"label": "A", "text": "Atlanto-Occipital", "correct": false}, {"label": "B", "text": "Atlanto-axial", "correct": true}, {"label": "C", "text": "C3-C4", "correct": false}, {"label": "D", "text": "C4-C5", "correct": false}], "correct_answer": "B. Atlanto-axial", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Atlanto-axial Left to right – “no” movement - Atlanto-axial joint</p>\n<p><strong>Highyeild:</strong></p><p>Nodding movement – “yes” movement - atlantooccipital joint Yes and No movement</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- - Option A. Atlanto-Occipital, option C. C3-C4and option D. C4-C5all are incorrect answers because Left to right – “no” movement takes at - Atlanto-axial joint.</p>\n<p><strong>Extraedge:</strong></p><p>The median atlantoaxial joint is formed between the dens of the axis and an osteoligamentous ring of the atlas anteriorly and transverse ligament posteriorly. It is classified as a pivot joint . The lateral atlantoaxial joints are bilateral joints formed between the lateral masses of the atlas and the axis. These joints are classified as gliding or plane joints.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 34 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Nerve supply of tip of nose:", "options": [{"label": "A", "text": "Ophthalmic Division", "correct": true}, {"label": "B", "text": "Maxillary nerve", "correct": false}, {"label": "C", "text": "Facial nerve", "correct": false}, {"label": "D", "text": "Mandibular division", "correct": false}], "correct_answer": "A. Ophthalmic Division", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ophthalmic Division The skin at the tip of the nose is supplied by the external nasal nerve is a branch of the anterior ethmoidal nerve which in turn is a branch from the nasociliary nerve (branch of the Ophthalmic nerve).</p>\n<p><strong>Highyeild:</strong></p><p>The sensory nerves of the face and neck. ( Supratrochlear, Supraorbital, Palpebral branch of lacrimal, Infratrochlear, External nasal, Infraorbital, Zygomaticofacial, Zygomaticotemporal, Auriculotemporal, Buccal, Mental, Great auricular, Transverse cutaneous nerve of neck, Lesser occipital, and Supraclavicular The sensory nerves of the face and neck.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Maxillary nerve, option C. Facial nerve, and option D. Mandibular division are incorrect answers because the skin at the tip of the nose is supplied by the External nasal nerve is a branch of the anterior ethmoidal nerve which in turn is a branch from the nasociliary nerve (branch of Ophthalmic nerve).</p>\n<p><strong>Extraedge:</strong></p><p>The ophthalmic nerve divides into three major branches as it passes through the superior orbital fissure. The nasociliary nerve gives off several sensory branches to the orbit. It then continues out through the anterior ethmoidal foramen, where it enters the nasal cavity. It provides innervation for much of the anterior nasal mucosa. It also gives off a branch that exits through the nasal bones to form the external nasal nerve. The lacrimal nerve passes through the orbit superiorly to innervate the lacrimal gland and part of the upper eyelid. The frontal nerve passes through the orbit superiorly. It passes through the supraorbital foramen to provide sensory innervation for the skin of the forehead and scalp through the supraorbital nerve and the supratrochlear nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The middle superior alveolar nerve is a branch of:", "options": [{"label": "A", "text": "Mandibular Nerve", "correct": false}, {"label": "B", "text": "Maxillary nerve", "correct": true}, {"label": "C", "text": "Lingual nerve", "correct": false}, {"label": "D", "text": "Facial nerve", "correct": false}], "correct_answer": "B. Maxillary nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Maxillary nerve The middle superior alveolar nerve or middle superior dental nerve is a branch from the infraorbital portion of the maxillary nerve to supply the sinus mucosa, the roots of the maxillary premolars, and the mesiobuccal root of the first maxillary molar.</p>\n<p><strong>Highyeild:</strong></p><p>The maxillary nerve gives off the following branches: A. In the Middle Cranial Fossa 1. Meningeal branch, which supplies the dura mater of the middle cranial fossa. B. In the Pterygopalatine Fossa Ganglionic (communicating) branches, two in number to pterygopalatine ganglion. Zygomatic nerve enters the orbit through an inferior orbital fissure and divides on the lateral wall of the orbit into: (a) A zygomaticotemporal branch, which passes through a foramen in the zygomatic bone to supply the skin of the temple. (b) A zygomaticofacial branch, which passes through the foramen in the zygomatic bone to supply the skin of the face. Posterior superior alveolar nerve enters one or two foramina on the posterior surface of the body of the maxilla and supplies the mucus membrane of the maxillary air sinus. Then it breaks up to form a superior dental plexus, which supplies the molar teeth and adjoining part of the gum. In the Orbit (infraorbital canal) Middle superior alveolar nerve passes downward and forward along the lateral wall of the maxillary sinus, joins the superior dental plexus, and supplies the premolar teeth. Anterior superior alveolar nerve runs in the anterior wall of the maxillary sinus through a bony canal and divides into dental and nasal branches: (a) The dental branches join the superior dental plexus and supply the canine and incisor teeth. (b) The nasal branches appear in the lateral wall of the inferior meatus and supply the mucus membrane of the lateral wall and floor of the nasal cavity. On the Face Palpebral branches turn upwards and supply the skin of the lower eyelid. Nasal branches supply the skin of the side of the nose and the mobile part of the nasal septum. Superior labial branches supply the skin and mucous membrane of the upper lip.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Mandibular Nerve Lingual nerve Facial nerve All of the above Options are incorrect answers because the middle superior alveolar nerve or middle superior dental nerve is a nerve is a branch from the infraorbital portion of the maxillary nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The superior dental plexus is formed by posterior, middle, and anterior superior alveolar nerves. It is situated in the alveolar process of the maxilla above the sockets of the teeth.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following muscles is not supplied by the anterior division of the mandibular nerve?", "options": [{"label": "A", "text": "Temporalis Muscle", "correct": false}, {"label": "B", "text": "Medial pterygoid muscle", "correct": true}, {"label": "C", "text": "Lateral pterygoid muscle", "correct": false}, {"label": "D", "text": "Masseter muscle", "correct": false}], "correct_answer": "B. Medial pterygoid muscle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Medial pterygoid muscle The nerve to the medial pterygoid is a branch from the trunk of the mandibular nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Branches of the mandibular nerve: From the main trunk: A. Meningeal branch B. Nerve to the medial pterygoid From the anterior trunk: A. A sensory branch—the buccal nerve B. Motor branches—the masseteric and deep temporal nerves and the nerve to the lateral pterygoid. From the posterior trunk: A. Auriculotemporal B. Lingual, and C. Inferior alveolar nerves. Branches of the mandibular nerve</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Temporalis Muscle The temporalis muscle is supplied by a branch from the anterior trunk of the mandibular nerve. Option C. Lateral pterygoid muscle The lateral pterygoid muscle is supplied by a branch from the anterior trunk of the mandibular nerve. Option D. Masseter muscle Masseter muscle is supplied by a branch from the anterior trunk of the mandibular nerve.</p>\n<p><strong>Extraedge:</strong></p><p>Trigeminal neuralgia : Pain along the distribution of the nerve which is caused due to local lesion or unknown cause. The principal disease affecting the sensory root of the V nerve is characterized by attacks of severe pain in the area of distribution of maxillary or mandibular divisions. The maxillary nerve is most frequently involved. The trigeminal ganglion harbors the herpes simplex virus causing herpes (shingles) in the distribution of the nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The structure which lies in close relation to the lower third molar is:", "options": [{"label": "A", "text": "Lingual Nerve", "correct": true}, {"label": "B", "text": "Inferior alveolar nerve", "correct": false}, {"label": "C", "text": "Facial nerve", "correct": false}, {"label": "D", "text": "Alveolar vein", "correct": false}], "correct_answer": "A. Lingual Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lingual Nerve The lingual nerve comes in direct contact with the mandible, medial to the 3rd molar tooth, and is covered only by mucous membrane.</p>\n<p><strong>Highyeild:</strong></p><p>The lingual nerve is marked by a curved line running downwards and forwards by joining these points: Point 3, on the posterior part of the mandibular notch, is in line with the mandibular nerve. Point 5, a little below and behind the last lower molar tooth. Point 6, opposite the first lower molar tooth. The concavity in the course of the nerve is more marked between the 5 and 6 points and is directed upwards.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Inferior alveolar nerve, option C. Facial nerve, and option D. Alveolar vein all are incorrect answers because, the lingual nerve comes in direct contact with the mandible, medial to the 3rd molar tooth, and is covered only by mucous membrane.</p>\n<p><strong>Extraedge:</strong></p><p>The lingual nerve carries sensory innervation from the anterior two-thirds of the tongue. It contains fibers from both the mandibular division of the trigeminal nerve (CN V 3 ) and from the facial nerve (CN VII). The fibers from the trigeminal nerve are for touch, pain, and temperature (general sensation), and the ones from the facial nerve are for taste (special sensation).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In Frey's syndrome, which postganglionic nerve innervates the sweat gland:", "options": [{"label": "A", "text": "Glossopharyngeal", "correct": false}, {"label": "B", "text": "Vagus", "correct": false}, {"label": "C", "text": "Facial", "correct": false}, {"label": "D", "text": "Trigeminal", "correct": true}], "correct_answer": "D. Trigeminal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Trigeminal Parotidectomy is the removal of the parotid gland. After this operation, at times, there may be aberrant regeneration of the secretomotor fibers in the auriculotemporal nerve (branch of the mandibular division of the trigeminal nerve) which join the great auricular nerve. This causes stimulation of the sweat glands and hyperaemia in the area of its distribution, thus producing redness and sweating in the area of skin supplied by the nerve. This clinical entity is called Frey’s syndrome . Whenever such a person chews there is increased sweating in the region supplied by the auriculotemporal nerve. So, it is also called ‘auriculotemporal syndrome’.</p>\n<p><strong>Highyeild:</strong></p><p>Connections of otic ganglion</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Glossopharyngeal, option B. Vagus, and option C. Facial are incorrect answers because, in the case of Frey’s syndrome, there may be aberrant regeneration of the secretomotor fibers in the auriculotemporal nerve (branch of the mandibular division of the trigeminal nerve) which join the great auricular nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The parotid calculi may get formed within the parotid gland or in its Stenson’s duct. These can be located by injecting a radio-opaque dye through its opening in the vestibule of the mouth. The procedure is called ‘Sialogram’. The duct can be examined by a spatula or bidigital examination.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The lacrimal gland is supplied by which of the following:", "options": [{"label": "A", "text": "Otic Ganglion", "correct": false}, {"label": "B", "text": "Ciliary ganglion", "correct": false}, {"label": "C", "text": "Pterygopalatine ganglion", "correct": true}, {"label": "D", "text": "Submandibular ganglion", "correct": false}], "correct_answer": "C. Pterygopalatine ganglion", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pterygopalatine ganglion Lacrimal gland parasympathetic innervation</p>\n<p><strong>Highyeild:</strong></p><p>The lacrimal gland receives blood from the lacrimal artery, which is a branch of the ophthalmic artery. Blood from the gland drains to the superior ophthalmic vein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:-- Option:A. Otic Ganglion Connections of otic ganglion Option:B. Ciliary ganglion Connections of ciliary ganglion Option:D. Submandibular ganglion Connections of submandibular ganglion</p>\n<p><strong>Extraedge:</strong></p><p>Branches of cervical sympathetic ganglia Superior cervical ganglion Middle cervical ganglion Inferior cervical ganglion Arterial branches i. Along internal carotid artery as internal carotid nerveii. Along common carotid and external carotid arteries Along inferior thyroid artery Along subclavian and vertebral arteries Grey rami communicantes along cervical and cranial nerves Along 1-4 cervical nerves Along cranial nerves IX, X, XI and XII Along 5 and 6 cervical nerves Along 7 and 8 cervical nerves Visceral branches Pharynx, cardiac Thyroid, cardiac Cardiac</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Dilator pupillae is supplied by:", "options": [{"label": "A", "text": "Oculomotor Nerve", "correct": false}, {"label": "B", "text": "Postganglionic sympathetic fibers from the otic ganglion", "correct": false}, {"label": "C", "text": "Postganglionic parasympathetic fibers from Edinger Westphal nucleus", "correct": false}, {"label": "D", "text": "Postganglionic sympathetic fibers from cervical ganglion", "correct": true}], "correct_answer": "D. Postganglionic sympathetic fibers from cervical ganglion", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Postganglionic sympathetic fibers from cervical ganglion The sympathetic root of the ciliary ganglion is a branch from the internal carotid plexus. It contains postganglionic fibers arising in the superior cervical ganglion (preganglionic fibers reach the ganglion from the lateral horn of the T1 spinal segment) which pass along internal carotid, ophthalmic, and long ciliary arteries. They pass out of the ciliary ganglion without relaying in the short ciliary nerves to supply the blood vessels of the eyeball. They also supply the dilator pupillae.</p>\n<p><strong>Highyeild:</strong></p><p>CILIARY GANGLION The ciliary ganglion is a peripheral parasympathetic ganglion placed in the course of the oculomotor nerve. It lies near the apex of the orbit between the optic nerve and the tendon of the lateral rectus muscle. It has parasympathetic, sensory, and sympathetic roots. The parasympathetic root arises from the nerve to the inferior oblique. It contains preganglionic fibers that begin in the Edinger-Westphal nucleus. The fibers relay in the ciliary ganglion. Postganglionic fibers arising in the ganglion pass through the short ciliary nerves and supply the sphincter pupillae and the ciliary The sensory root comes from the nasociliary nerve. It contains sensory fibers for the eyeball. The fibers do not relay in the ganglion. The sympathetic root is a branch from the internal carotid plexus. It contains postganglionic fibers arising in the superior cervical ganglion (preganglionic fibers reach the ganglion from the lateral horn of the T1 spinal segment) which pass along internal carotid, ophthalmic, and long ciliary arteries. They pass out of the ciliary ganglion without relaying in the short ciliary nerves to supply the blood vessels of the eyeball. They also supply the dilator pupillae. Connections of ciliary ganglion</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Oculomotor Nerve Oculomotor function Motor The oculomotor nerves send somatic motor fibers to all extraocular muscles, except the superior oblique and lateral rectus. The superior branch supplies the superior rectus which elevates the eyeball, and the levator palpebrae superioris which raises the upper eyelid. The inferior branch innervates the medial rectus which adducts the eyeball, the inferior rectus which depresses the eyeball, and the inferior oblique which elevates, abducts, and laterally rotates the eyeball. Parasympathetic There are two primary functions of the autonomic parasympathetic (involuntary) oculomotor nerve. It constricts the pupil (miosis) by innervating the smooth muscle (sphincter pupillae) near the pupil. It also innervates the ciliary muscles. The sphincter pupillae causes the narrowing of the pupil in order to prevent diverging light rays from the corneal periphery creating a blurred image. The ciliary muscle changes the shape of the lens during accommodation. Sympathetic The oculomotor nerve has no direct function, but sympathetic fibers run with the oculomotor nerve to innervate the superior tarsal muscle (helps to raise the eyelid). Option B. Postganglionic sympathetic fibers from the otic ganglion Postganglionic sympathetic fibers from otic ganglion send sympathetic vasomotor fibers to the parotid gland. Option C. Postganglionic parasympathetic fibers from Edinger Westphal nucleus The Edinger-Westphal nucleus contains a group of parasympathetic preganglionic cells that innervate the ciliary muscle and the pupillary constrictor. The axons of these cholinergic preganglionic neurons synapse with ganglion cells in the ciliary ganglion.</p>\n<p><strong>Extraedge:</strong></p><p>The corneal reflex pathway.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All the structures pass through the optic foramen, except:", "options": [{"label": "A", "text": "Optic Nerve", "correct": false}, {"label": "B", "text": "Ophthalmic artery", "correct": false}, {"label": "C", "text": "Ophthalmic nerve", "correct": true}, {"label": "D", "text": "Dura mater", "correct": false}], "correct_answer": "C. Ophthalmic nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ophthalmic nerve The ophthalmic nerve enters the superior orbital fissure by diving into 3 branches prior to the fissure itself (in the anterior part of the cavernous sinus, the nerve divides into the lacrimal, frontal, and nasociliary nerves). Structure passing through Superior orbital fissure and optic canal</p>\n<p><strong>Highyeild:</strong></p><p>Structures passing through Optic Foramen Optic nerve: along with its sheath of meninges, i.e., dura mater, arachnoid mater, and pia mater. Ophthalmic artery: a branch of the cerebral part of the internal carotid artery. Sympathetic plexus around the ophthalmic artery.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Optic Nerve Ophthalmic artery Dura mater All the structures mentioned in Options A, B, and C pass through optic foramen.</p>\n<p><strong>Extraedge:</strong></p><p>The optic foramen is the opening to the optic canal. The canal is located in the sphenoid bone ; it is bounded medially by the body of the sphenoid and laterally by the lesser wing of the sphenoid.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient was diagnosed with a tumor in the base of the skull obscuring a part of the jugular foramen. You suspect the 11th Cranial Nerve to be involved. This can be confirmed by testing the actions of the following muscles, EXCEPT-", "options": [{"label": "A", "text": "Palatopharyngeus", "correct": false}, {"label": "B", "text": "Levator palatini", "correct": false}, {"label": "C", "text": "Tensor veli palatini", "correct": true}, {"label": "D", "text": "Palatoglossus", "correct": false}], "correct_answer": "C. Tensor veli palatini", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Tensor veli palatini All muscles of the palate are supplied by the Cranial Accessory Nerve via the vagus accessory complex except tensor veli palatini.</p>\n<p><strong>Highyeild:</strong></p><p>All muscles of the pharynx are supplied by the vagus accessory complex except Stylopharyngeus which is supplied by the Glossopharyngeal nerve. Tensor veli palatini develops in the 1st Pharyngeal arch and is supplied by the Mandibular branch of the Trigeminal Nerve (Medial Pterygoid Nerve).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Palatopharyngeus Option B. Levator palatini Option D. Palatoglossus The muscles innervated directly by the XI nerve are the trapezius and the sternocleidomastoid. The cranial component of the accessory nerve, on the other hand, provides motor control to the muscles of the soft palate, larynx, and pharynx, except tensor veli palatini and stylopharyngeus muscles.</p>\n<p><strong>Extraedge:</strong></p><p>The accessory nerve is derived from the basal plate of the embryonic spinal segments C1–C6.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During the viva of Anatomy practical exam, the Professor of Anatomy marked a ganglion as shown in the image and questioned “Everything is CORRECT regarding the location of this ganglion EXCEPT”:", "options": [{"label": "A", "text": "Anterior to Middle Meningeal Artery", "correct": false}, {"label": "B", "text": "Lateral to Mandibular Nerve", "correct": true}, {"label": "C", "text": "Lateral to Tensor Veli Palatini", "correct": false}, {"label": "D", "text": "Inferior to Foramen Ovale", "correct": false}], "correct_answer": "B. Lateral to Mandibular Nerve", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681465307-QTDA029011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral to Mandibular Nerve The marked structure given in the image is of Otic ganglion. The otic ganglion is Medial (deeper) to Mandibular Nerve. Otic ganglion lies Inferior to Foramen Ovale. The otic ganglion lies Lateral to the Tensor Veli Palatini muscle. Otic ganglion lies Anterior to Middle Meningeal Artery and Posterior to Medial Pterygoid Muscle. Otic ganglion</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Anterior to Middle Meningeal Artery Otic ganglion lies Anterior to Middle Meningeal Artery and Posterior to Medial Pterygoid Muscle. Option:C. Lateral to Tensor Veli Palatini The otic ganglion lies the Lateral to Tensor Veli Palatini muscle. Option:D. Inferior to Foramen Ovale Otic ganglion lies Inferior to Foramen Ovale.</p>\n<p><strong>Extraedge:</strong></p><p>The otic ganglion lies deep in the trunk of the mandibular nerve, between the nerve and the tensor veli palatini muscle in the infratemporal fossa, just distal to the foramen ovale. Topographically, it is connected to the mandibular nerve, while functionally it is related to cranial nerve IX.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Maxillary Nerve exits the skull via _____", "options": [{"label": "A", "text": "Foramen Rotundum", "correct": true}, {"label": "B", "text": "Foramen Ovale", "correct": false}, {"label": "C", "text": "Foramen Spinosum", "correct": false}, {"label": "D", "text": "Foramen Lacerum", "correct": false}], "correct_answer": "A. Foramen Rotundum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Foramen Rotundum Maxillary Nerve is a branch of the Trigeminal nerve present in the floor of the middle cranial fossa and passes through Foramen Rotundum.</p>\n<p><strong>Highyeild:</strong></p><p>The foramen rotundum is a circular hole in the sphenoid bone that connects the middle cranial fossa and the pterygopalatine fossa. The foramen rotundum allows the passage of the maxillary nerve (V 2 ), a branch of the trigeminal nerve. It also allows the passage of the artery of the foramen rotundum and an emissary’s vein.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Otion:B. Foramen Ovale Lateral to foramen rotundum, there is Foramen Ovale present through which the Mandibular nerve passes and supplies the mandible. Option:C. Foramen Spinosum The Middle Meningeal Artery passes through Foramen Spinosum. Option:D. Foramen Lacerum</p>\n<p><strong>Extraedge:</strong></p><p>Emissary’s veins pass through Foramen Lacerum. Foramen ovale is present in the posterior part of the greater wing of the sphenoid. The important structures which pass through it are the mandibular nerve, the accessory meningeal artery, the lesser superficial petrosal nerve, and the emissary</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During the neurologic examination of a 44 yr old male patient in the ward, you use a wisp of cotton and bring it from laterally and touch the cornea to elicit a Reflex. You find that it is lost and a possible reason could be an injury to the.", "options": [{"label": "A", "text": "Optic N.", "correct": false}, {"label": "B", "text": "Oculomotor N.", "correct": false}, {"label": "C", "text": "Ophthalmic N.", "correct": true}, {"label": "D", "text": "Trochlear N.", "correct": false}], "correct_answer": "C. Ophthalmic N.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ophthalmic N. The Question is about Corneal Reflex. The afferent limb of the corneal reflex is the Ophthalmic division of Trigeminal N. The efferent limb of the corneal reflex is Facial N. Injury to any of the above may result in loss of corneal reflex.</p>\n<p><strong>Highyeild:</strong></p><p>The Corneal reflex is mediated by: The nasociliary branch of the ophthalmic branch (V 1 ) of the trigeminal nerve (CN V) senses the stimulus on the cornea only (afferent fiber). The temporal and zygomatic branches of the facial nerve (CN VII) initiates the motor response (efferent fiber). The center (nucleus) is located in the pons of the brainstem.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Optic N, Option B. Oculomotor N., and Option D. Trochlear N are all incorrect answers because the afferent limb of the corneal reflex is the Ophthalmic division of the Trigeminal nerve and the efferent limb of the corneal reflex is the Facial nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The corneal reflex pathway</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are branches of the Mandibular Nerve EXCEPT: Auriculotemporal N. Inferior Alveolar N. Lingual N. Zygomatic N. Select the correct answer given below code:", "options": [{"label": "A", "text": "2 Only", "correct": false}, {"label": "B", "text": "1, 2 & 3 only", "correct": false}, {"label": "C", "text": "4 only", "correct": true}, {"label": "D", "text": "3 only", "correct": false}], "correct_answer": "C. 4 only", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4 only The zygomatic nerve is a branch of the Maxillary division of the Trigeminal nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Branches of mandibular nerve: From the main trunk: A. Meningeal branch B. Nerve to the medial pterygoid. From the anterior trunk: A. A sensory branch—the buccal nerve B. Motor branches—the masseteric and deep temporal nerves and the nerve to the lateral pterygoid. From the posterior trunk: A. Auriculotemporal, B. Lingual, and C. Inferior alveolar nerves.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. 2 Only, Option B. 1, 2 & 3 only, and option D. 3 only, are all incorrect answers because, Auriculotemporal Nerve, Inferior Alveolar Nerve, and Lingual Nerve are branches of the mandibular nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The mandibular nerve is the only branch of the trigeminal nerve that contains a motor root. In the infratemporal fossa, near the skull base, the main trunk immediately gives off the sensory meningeal branch and motor muscular branches to the medial pterygoid, tensor tympani, and tensor veli palatini muscles</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following are branches of the Ophthalmic division of theTrigeminal Nerve, EXCEPT:", "options": [{"label": "A", "text": "Supratrochlear N.", "correct": false}, {"label": "B", "text": "Infratrochlear N.", "correct": false}, {"label": "C", "text": "Supraorbital N.", "correct": false}, {"label": "D", "text": "Infraorbital N.", "correct": true}], "correct_answer": "D. Infraorbital N.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Infraorbital N. The infraorbital nerve represents the terminal branch of the maxillary nerve . The infraorbital nerve courses forward, first through the infraorbital groove, and then through the infraorbital canal on the floor of the orbit.</p>\n<p><strong>Highyeild:</strong></p><p>Branches of Ophthalmic division of Trigeminal nerve: Supratrochlear N. Supraorbital N. Lacrimal N. Infratrochlear N. External Nasal N.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Supratrochlear N. Infratrochlear N. Supraorbital N.</p>\n<p><strong>Extraedge:</strong></p><p>The infraorbital nerve is a branch of the Maxillary division of the Trigeminal Nerve. Supratrochlear, Supraorbital, and Infratrochlear nerves are branches of the ophthalmic division of trigeminal nerve. The infraorbital nerve provides sensory innervation to the lower eyelid, lateral aspect of the nose, upper lip, upper incisor, canine, premolars, and mesiobuccal root of the first molar on the ipsilateral side of the face.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient suffers from Frey’s syndrome manifested by perspiration of the skin covering the left parotid gland whenever the patient eats. On inquiry, the patient reveals that he suffered deep injuries on the side of his face and neck in an automobile accident. You explain to him that his syndrome results from abnormal connections between the great auricular nerve and parasympathetic secretomotor fibers, which normally innervate only the parotid gland. This abnormal reinnervation occurred during the healing period after the accident. The parasympathetic secretomotor fibers to the parotid gland are carried by which of the following?", "options": [{"label": "A", "text": "Auriculotemporal Nerve", "correct": true}, {"label": "B", "text": "Buccal branch of the facial nerve", "correct": false}, {"label": "C", "text": "Buccal nerve", "correct": false}, {"label": "D", "text": "Greater petrosal nerve", "correct": false}], "correct_answer": "A. Auriculotemporal Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Auriculotemporal Nerve The auriculotemporal nerve is a branch of the mandibular division of the trigeminal nerve. It carries postganglionic parasympathetic fibers from the otic ganglion to the parotid gland. It is the most commonly involved nerve in Frey’s syndrome.</p>\n<p><strong>Highyeild:</strong></p><p>In the case of Frey’s syndrome, Whenever such a person chews there is increased sweating in the region supplied by the auriculotemporal nerve. So, it is also called ‘auriculotemporal syndrome’.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B. The buccal branch of the facial nerve provides motor innervation to the muscles around the mouth. Option: C. The buccal nerve is a sensory branch of the mandibular division of the trigeminal nerve. It innervates the gingiva adjacent to the two posterior molar teeth, the mucosa, and the skin of the cheek. Option: D. The greater petrosal nerve is a branch of the facial nerve from the geniculate ganglion. It carries preganglionic parasympathetic fibers to the pterygopalatine ganglion. The lesser petrosal nerve is a continuation of the tympanic branch of the glossopharyngeal nerve and carries preganglionic parasympathetic fibers to the otic ganglion.</p>\n<p><strong>Extraedge:</strong></p><p>A parotid abscess is best drained by horizontal incision/making many small holes known as Hilton’s method below the angle of the mandible.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 25 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "All are true about Fibrous pericardium except:", "options": [{"label": "A", "text": "It is a conical sac", "correct": false}, {"label": "B", "text": "Apex lies at sternal angle level", "correct": false}, {"label": "C", "text": "Base lies on central tendon of diaphragm", "correct": false}, {"label": "D", "text": "Anteriorly related to esophagus", "correct": true}], "correct_answer": "D. Anteriorly related to esophagus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anteriorly related to esophagus Anteriorly, Fibrous pericardium is connected to the upper and lower ends of the body of the sternum by superior and inferior sternopericardial ligaments.</p>\n<p><strong>Highyeild:</strong></p><p>The fibrous pericardium is the outside layer of the pericardium, made up of dense and loose connective tissue. It i s continuous with the outer adventitial layer of the neighboring great blood vessels, fused with the central fibrous area of the diaphragm on its posterior aspect and attached to the posterior surface of the sternum by the sternopericardial ligaments. Pericardium of Heart</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. It is a conical sac Fibrous pericardium is a conical sac made up of fibrous tissue. Fibrous pericardium is capable of some change in shape, it is largely non-pliable, which acts to protect the heart against blunt forces and sudden pressure change from the outside. Option B. Apex lies at sternal angle level The apex is blunt and lies at the level of the sternal angle.(Option B). The fibrous pericardium is a conical-shaped sac. Its apex is fused with the roots of the great vessels at the base of the heart . Its broad base overlies the central fibrous area of the diaphragm with which it is fused. Option C. Base lies on central tendon of diaphragm Base of Fibrous pericardium is broad and inseparably blended with the central tendon of the diaphragm .(Option C) It is fused with the roots of the great vessels and with the pretracheal fascia. Anteriorly, it is connected to the upper and lower ends of the body of the sternum by superior and inferior sternopericardial ligaments. Posteriorly, it is related to the principal bronchi, the esophagus with the nerve plexus around it and the descending thoracic aorta. On each side, it is related to the mediastinal pleura, the mediastinal surface of the lung, the phrenic nerve, and the pericardiophrenic vessels. It protects the heart against sudden overfilling and prevents overexpansion of the heart.</p>\n<p><strong>Extraedge:</strong></p><p>The pericardium is a tough fibroelastic sac which covers the heart from all sides except at the cardiac root (where the great vessels join the heart) and the bottom (where only the serous pericardium exists to cover the upper surface of the central tendon of diaphragm). The fibrous pericardium is semi-rigid, while the serous pericardium is quite pliable.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is true about serous pericardium?", "options": [{"label": "A", "text": "It is a double layered serous membrane", "correct": true}, {"label": "B", "text": "Lined by stratified squamous epithelium", "correct": false}, {"label": "C", "text": "Two layers are not continuous with each other", "correct": false}, {"label": "D", "text": "There is no potential space between two layers of Serous pericardium", "correct": false}], "correct_answer": "A. It is a double layered serous membrane", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>It is a double layered serous membrane Serous pericardium is thin, double-layered serous membrane lined by mesothelium. The serous pericardium , is divided into two parts: Parietal serous pericardium, which lines the interior side of the superficial portion of the pericardial sac, is fused to and inseparable from the fibrous pericardium Visceral serous pericardium, also known as the epicardium, covers the myocardium of the heart and can be considered its serosa. It is largely made of a mesothelium overlying some elastin-rich loose connective tissue. During ventricular contraction, the wave of depolarization moves from the endocardial to the epicardial surface. Pericardium</p>\n<p><strong>Highyeild:</strong></p><p>Visceral serous pericardium extends to the root of the great vessels and joins the parietal serous pericardium at the anatomical base of the heart. This junction occurs at two areas: the ventricular outflow tracts where the aorta and pulmonary trunk leave the heart, and the inflow tracts where the superior/inferior vena cava and pulmonary veins enter the heart.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Lined by stratified squamous epithelium It is lined by mesothelium. (OPTION B) The outer layer or parietal pericardium is fused with the fibrous pericardium. The inner layer or the visceral pericardium, or epicardium is fused to the heart, except along the cardiac grooves, where it is separated from the heart by blood vessels. Option C. Two layers are not continuous with each other The two layers are continuous with each other at the roots of the great vessels, i.e., ascending aorta, pulmonary trunk, two venae cava, and four pulmonary veins. (OPTION C) Option D. There is no potential space between two layers of Serous pericardium The pericardial cavity is a potential space between the parietal pericardium and the visceral pericardium. (OPTION D) It contains only a thin film of serous fluid which lubricates the apposed surfaces and allows the heart to beat smoothly</p>\n<p><strong>Extraedge:</strong></p><p>Mesothelium that constitutes the serous pericardium also covers the heart as the epicardium, resulting in a continuous serous membrane invaginated onto itself as two opposing surfaces (over the fibrous pericardium and over the heart). This creates a pouch-like potential space around the heart enclosed between the two opposing serosal surfaces, known as the pericardial space or pericardial cavity , which is filled with a small amount of serous fluid to lubricate the heart's movements and cushions it from any external jerk or shock.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not the contents of Pericardium?", "options": [{"label": "A", "text": "Heart and coronary vessels", "correct": false}, {"label": "B", "text": "Root of great arteries", "correct": false}, {"label": "C", "text": "Complete inferior vena cava", "correct": true}, {"label": "D", "text": "Terminal part if pulmonary veins", "correct": false}], "correct_answer": "C. Complete inferior vena cava", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Complete inferior vena cava Complete inferior vena cava is not the content of pericardium. The inferior vena cava is a large vein that carries the deoxygenated blood from the lower and middle body into the right atrium of the heart. It is f ormed by the joining of the right and the left common iliac veins, usually at the level of the fifth lumbar vertebra.</p>\n<p><strong>Highyeild:</strong></p><p>The IVC is formed by the joining of the left and right common iliac veins and brings collected blood into the right atrium of the heart. It also joins with the azygos vein (which runs on the right side of the vertebral column) and venous plexuses next to the spinal cord. The inferior vena cava begins as the left and right common iliac veins behind the abdomen unite, at about the level of L5.It passes through the thoracic diaphragm at the caval opening at the level of T8 - T9.It passes to the right of the descending aorta.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Heart and coronary vessels Option B. Root of great arteries Option D. Terminal part if pulmonary veins Option A, B and D are all content of pericardium. Contents of Pericardium Heart with cardiac vessels and nerves (Option A) Ascending aorta (Option B) Pulmonary trunk Lower half of the superior vena cava Terminal part of the inferior vena cava The terminal parts of the pulmonary veins (Option D)</p>\n<p><strong>Extraedge:</strong></p><p>I nferior vena cava is located to the right of the midline, drainage of the tributaries is not always symmetrical. On the right, the gonadal veins and suprarenal veins drain into the inferior vena cava directly.On the left, they drain into the renal vein which in turn drains into the inferior vena cava. All the lumbar veins and hepatic veins usually drain directly into the inferior vena cava.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statements is false about transverse sinus?", "options": [{"label": "A", "text": "Bounded anteriorly by the arterial end and posteriorly by the venous end", "correct": false}, {"label": "B", "text": "Develops from ventral mesocardium", "correct": true}, {"label": "C", "text": "In mitral stenosis, left atrium is enlarged and compresses the esophagus causing dysphagia", "correct": false}, {"label": "D", "text": "During heart surgery, the ligature is passed through the transverse sinus around the aorta and the pulmonary trunk.", "correct": false}], "correct_answer": "B. Develops from ventral mesocardium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Develops from ventral mesocardium Transverse sinus develops from degeneration of the central part of dorsal mesocardium.</p>\n<p><strong>Highyeild:</strong></p><p>Transverse sinus is the tunnel-shaped passage posterior to the aorta and pulmonary trunk , and anterior to the superior vena cava. This sinus is clinically important because passing one end of clamp through the sinus, and the other end anterior to the aorta/pulmonary trunk will allow complete blockage of blood output. This is performed during some heart surgeries. Transverse sinus of Pericardium</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A: It is bounded anteriorly by the ascending aorta and pulmonary trunk, and posteriorly by the superior vena cava and inferiorly by the left atrium; on each side, it opens into the general pericardial cavity. Option C: Esophagus lies behind the left atrium, enlargement of which can result in compression of esophagus. Option D: The transverse sinus is a horizontal gap between the arterial and venous ends of the heart tube.</p>\n<p><strong>Extraedge:</strong></p><p>The oblique sinus is an inverted J-shaped reflection of the venae cavae and pulmonary veins. It lies behind the atria (particularly the left atrium), and in between left and right pulmonary veins.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statement is not true about oblique sinus?", "options": [{"label": "A", "text": "Present Behind Heart", "correct": false}, {"label": "B", "text": "Anteriorly related to right atrium", "correct": true}, {"label": "C", "text": "Permits pulsations of left atrium to take place smoothly", "correct": false}, {"label": "D", "text": "Posteriorly related to esophagus", "correct": false}], "correct_answer": "B. Anteriorly related to right atrium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anteriorly related to right atrium The oblique pericardial sinus is a blind-ending pericardial cul-de-sac behind the heart which opens into the pericardial space proper inferiorly. Anteriorly lies the heart, specifically the posterior wall of the left atrium and posteriorly the pericardium and esophagus. The oblique sinus forms the posterior pericardial recess.</p>\n<p><strong>Highyeild:</strong></p><p>Oblique Pericardial sinus boundaries are: Right (in ascending order): inferior vena cava, right inferior pulmonary vein and right superior pulmonary vein Superior: it is separated from the transverse pericardial sinus above by a double reflection of serous pericardium that extends transversely between the left and right superior pulmonary veins Left (in ascending order): left inferior pulmonary vein and left superior pulmonary vein. Oblique sinus of Pericardium</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Present Behind Heart The oblique sinus is a narrow gap behind the heart. It is bounded anteriorly by the left atrium, posteriorly by the parietal pericardium and esophagus. Option C. Permits pulsations of left atrium to take place smoothly The oblique sinus permits pulsations of the left atrium to take place freely. It develops due to rearrangement of veins at the venous end. Option D. Posteriorly related to esophagus The oblique sinus is a narrow gap behind the heart. It is bounded anteriorly by the left atrium, posteriorly by the parietal pericardium and esophagus.</p>\n<p><strong>Extraedge:</strong></p><p>Several other pericardial recesses form small pockets that may extend towards the oblique sinus, which may mimic mediastinal lymph nodes or disease: aortic recesses superior aortic recess inferior aortic recess pulmonic recesses right pulmonic recess left pulmonic recess postcaval recess pulmonary venous recesses right pulmonary venous recess left pulmonary venous recess</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statement is false about pericardium?", "options": [{"label": "A", "text": "Blood supply is from the internal thoracic artery.", "correct": false}, {"label": "B", "text": "Fibrous Pericardium is pain insensitive", "correct": true}, {"label": "C", "text": "Epicardium is supplied by autonomic nerves of the heart and is not sensitive to pain.", "correct": false}, {"label": "D", "text": "Pain of pericarditis originates in the parietal pericardium alone while cardiac pain or angina originates in the cardiac muscle or in the vessels of the heart.", "correct": false}], "correct_answer": "B. Fibrous Pericardium is pain insensitive", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fibrous Pericardium is pain insensitive Nerve Supply of Fibrous Pericardium The fibrous and parietal pericardium are supplied by the phrenic nerves. They are sensitive to pain.(OPTION B) The epicardium is supplied by autonomic nerves of the heart and is not sensitive to pain.</p>\n<p><strong>Highyeild:</strong></p><p>The pericardium, also called pericardial sac, is a double-walled sac containing the heart and the roots of the great vessels. It has two layers, an outer layer made of strong connective tissue (fibrous pericardium), and an inner layer made of serous membrane (serous pericardium). It encloses the pericardial cavity, which contains pericardial fluid, and defines the middle mediastinum. It separates the heart from interference of other structures, protects it against infection and blunt trauma, and lubricates the heart's movements.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Blood supply is from internal thoracic artery The fibrous and parietal pericardium are supplied by branches from: Internal thoracic arteries(OPTION A) Musculophrenic arteries The descending thoracic aorta Veins drain into corresponding veins Option C. Epicardium is supplied by autonomic nerves of the heart and is not sensitive to pain. Nerves and blood vessels that supply the heart are found in the epicardium. At the roots of great vessels, the epicardium reflects back and continues as the parietal pericardium, forming an enclosed pericardial sac. The sac is filled with serous pericardial fluid that prevents friction during heart contractions. Option D. Pain of pericarditis originates in the parietal pericardium alone while cardiac pain or angina originates in the cardiac muscle or in the vessels of the heart. Pain of pericarditis originates in the parietal pericardium alone. P ericarditis is inflammation of the pericardium, the fibrous sac surrounding the heart. Symptoms typically include sudden onset of sharp chest pain, which may also be felt in the shoulders, neck, or back. The pain is typically less severe when sitting up and more severe when lying down or breathing deeply. Other symptoms of pericarditis can include fever, weakness, palpitations, and shortness of breath. On the other hand, Cardiac pain or angina originates in the cardiac muscle or in the vessels of the heart.</p>\n<p><strong>Extraedge:</strong></p><p>Fibrous pericardium is derived from the septum transversum in the embryo. The septum transversum is a thick mass of cranial mesenchyme that is formed on day 22. During craniocaudal folding, it assumes a position caudal to the developing heart.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not a feature of pericardial effusion ?", "options": [{"label": "A", "text": "Pulsus paradoxus is seen", "correct": false}, {"label": "B", "text": "Beck’s triad is seen", "correct": false}, {"label": "C", "text": "JVP is raised", "correct": false}, {"label": "D", "text": "Systolic compression of heart", "correct": true}], "correct_answer": "D. Systolic compression of heart", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Systolic compression of heart Collection of fluid in the pericardial cavity is referred to as pericardial effusion/cardiac tamponade. The fluid compresses the heart and restricts venous filling during diastole.</p>\n<p><strong>Highyeild:</strong></p><p>Pericardial effusion can be drained by puncturing the left fifth or sixth intercostal space just lateral to the sternum , or in the angle between the xiphoid process and left costal margin, with the needle directed upwards, backwards and to the left.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect Options : Option A. Pulsus paradoxus is seen In pericardial effusion, the presence of pulsus paradoxus has a greater than 80% sensitivity for tamponade, and strongly increases the likelihood that tamponade is present. However, the absence of pulsus paradoxus does not exclude a diagnosis of cardiac tamponade. Pulsus paradoxus is seen characterized by fall in SBP > 10mmHg with inspiration Option B. Beck’s triad is seen Classic presentation of patients with pericardial effusion will have muffled heart sounds and Beck's triad. Beck's triad(hypotension, distended neck veins and muffled heart sounds) will be present in patients with pericardial tamponade. Option C. JVP is raised JVP is raised in Pericardial effusion cases. OPTION C: Beck’s triad is seen Hypotension Raised JVP Muffled heart sound</p>\n<p><strong>Extraedge:</strong></p><p>Pericardial effusion Any process that leads to injury or inflammation of the pericardium and/or inhibits appropriate lymphatic drainage of the fluid from the pericardial cavity leads to fluid accumulation. Out of all the numerous causes of pericardial effusion, some of the leading causes are inflammatory, infectious, neoplastic and traumatic. These causes can be categorized into various classes, but an easy way to understand them is dividing them into inflammatory versus non-inflammatory.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 44y old male complained of hematemesis and was admitted to the ER. On examination of patients, vitals show hypotension and tachycardia. The patient's wife gives a history of chronic alcoholism. An endoscopy shows the following Image. What is the diagnosis?", "options": [{"label": "A", "text": "Esophageal Cancer", "correct": false}, {"label": "B", "text": "GERD", "correct": false}, {"label": "C", "text": "Esophagitis", "correct": false}, {"label": "D", "text": "Liver cirrhosis", "correct": true}], "correct_answer": "D. Liver cirrhosis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391854822-QTDA007001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Liver cirrhosis Esophageal varices occur in the lower 1/3rd of the esophagus, a site of the Portacaval anastomoses. Liver cirrhosis is primarily caused by alcoholic behavior. It causes portal hypertension. Hence, esophageal varices occur in the esophagus, a site of the Portacaval anastomoses. It causes hematemesis. Excessive blood loss causes shock. Endoscopic band ligation can be done for treatment.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Esophageal cancers are caused by smoking and poorly controlled acid reflux. The symptoms include trouble in swallowing, unintentional weight loss, chest pain, angina, and coughing or hoarseness. There is no enlargement of the esophageal veins. Hence, it is the wrong answer. Option: B. GERD is a gastroesophageal reflux disorder due to the malfunctioning of the lower esophageal sphincter. It doesn’t cause hematemesis and shock. Hence, it is the wrong answer. Option: C. Esophagitis is the inflammation of the esophagus that can be due to bacterial infections. The symptoms include pain, difficulty swallowing, and chest pain while eating. It doesn’t cause hematemesis and shock. Hence, it is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 50y old female patient diagnosed with appendicitis presents with protrusion of the abdomen which on examination shows dull on percussion. There are complaints of inability to flex the hip and nausea. What is the procedure shown in the Image to alleviate the swelling?", "options": [{"label": "A", "text": "Cordocentesis", "correct": false}, {"label": "B", "text": "Paracentesis", "correct": false}, {"label": "C", "text": "Culdocentesis", "correct": true}, {"label": "D", "text": "Cysto centesis", "correct": false}], "correct_answer": "C. Culdocentesis", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686391855624-QTDA007002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Culdocentesis Culdocentesis is a process of extracting this fluid from the rectouterine pouch of Douglas. Culdocentesis is the process of fluid extraction from the rectouterine pouch of Douglas . This is performed by inserting a needle through the posterior fornix of the vagina. It is used to extract excess fluid from the peritoneal cavity or to drain a pelvic abscess in the rectouterine pouch in cases of ovarian cysts and ectopic pregnancies. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Cordocentesis is also known as percutaneous umbilical cord blood sampling. It is a prenatal diagnostic test. Here, an ultrasound transducer is used to determine the fetus's and umbilical cord's position. Then a fetal blood sample is then collected from the umbilical cord for further testing. Hence, it is the wrong answer. Option: B. Paracentesis is also a type of body fluid sampling procedure. It is also referred to as peritoneocentesis, paracentesis, or abdominal paracentesis. Here, the peritoneal cavity is punctured by a needle to sample peritoneal fluid or remove the excess liquid. Hence, it is the wrong answer. Option: D. Cystocentesis is a veterinary procedure. Here, a needle is placed into the urinary bladder through the abdominal wall to remove a urine sample or assist in micturition in some conditions. Hence, it is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A female in her forties is brought to the physician. She complains of intense pain in the upper right portion of her abdomen; she further says she experiences occasional pain over her right shoulder. Examination of the stool signifies that it is light-colored, foul-smelling, and less dense. Murphy's sign is negative. Which of the following disorders can produce a similar type of icterus?", "options": [{"label": "A", "text": "Diverticulosis", "correct": false}, {"label": "B", "text": "Pancreatic cancer", "correct": true}, {"label": "C", "text": "Celiac disease", "correct": false}, {"label": "D", "text": "Inflammatory bowel diseases", "correct": false}], "correct_answer": "B. Pancreatic cancer", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pancreatic cancer The clinical vignette comes to a diagnosis of cholelithiasis. It can cause obstructive jaundice (Icterus) due to obstruction of the biliary tract. In obstructive jaundice, the bile pigments aren't released into the GIT. Hence the stool is light-colored. Also, lacking bile salts reduces fat absorption, resulting in less dense (floating) and foul-smelling stool. Pancreatic head cancer can result in obstructive jaundice; hence it is the correct answer. The head and uncinate process of the pancreas is closely related to the bile duct. Accordingly, cancer can compress it, resulting in obstructive jaundice.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Diverticulosis is the formation of pockets in the wall of the large intestine. It doesn't manifest with symptoms unless they get inflamed (diverticulitis). Hence it is the wrong answer. Option: C. Celiac disease is an immune disease wherein the patient presents with diarrhea, bloating, and anemia in response to gluten in the diet. Hence, it is the wrong answer. Option: D. Inflammatory bowel diseases like Crohn's disease and tropical sprue present with pain in the middle and lower quadrants of the abdomen due to the inflammation of the abdominal tract. Hence, it is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An alcoholic patient is brought to the ER with severe bleeding from the liver. Blood clotting agents were ineffective in stopping the bleeding. The patient was shifted to the OR for liver transplantation as a last resort. The surgeon wants to stop the liver from bleeding. Which of the following maneuvers will he/ she apply?", "options": [{"label": "A", "text": "Kocher Maneuver", "correct": false}, {"label": "B", "text": "Pringle maneuver", "correct": true}, {"label": "C", "text": "Cattell maneuver", "correct": false}, {"label": "D", "text": "Mattox maneuver", "correct": false}], "correct_answer": "B. Pringle maneuver", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pringle maneuver The hepatic artery is a component of the portal triad. Hence, a maneuver that involves clamping of this artery is called the Pringle maneuver. The patient is suffering from severe liver cirrhosis as he is an alcoholic. The brutal blood loss is due to variceal bleeding caused by portal hypertension. The surgeon can stop the bleeding by preventing blood flow to the liver. This is done by obliterating the hepatic artery. Pringle maneuver is the clamping of the portal triad in the hepatoduodenal ligament, a part of the lesser omentum. The hepatic artery is one of the blood supplies to the liver. Hence, clamping would restrict blood flow significantly, thus stopping the bleeding to an extent. Therefore, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Kocher maneuver is the dissection of the peritoneal attachments of the duodenum laterally. It is done to create a space for inspecting the duodenum, pancreas, and other retroperitoneal structures. Hence, it is the wrong answer. Option: C. Cattle maneuver is a method of mobilization during surgeries. This maneuver allows access to the retroperitoneal structures. After the completion, the inferior vena cava, the abdominal part of the aorta below the superior mesenteric artery, and the retroperitoneal organs on the right side are exposed. Hence, it is the wrong answer. Option: D. Mattox maneuver is an experimental technique to access the left and central retroperitoneal organs and vessels. Hence, it is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An AIDS patient with severe right hypochondriac pain is admitted to a physician. The patient presents with mild icterus and complains of nausea, vomiting, bloating, and pain in the upper right shoulder. Murphy's sign is positive. Serum amylase and lipase levels are normal. An abdominal ultrasound shows no sign of stones in the biliary apparatus. What is the most probable diagnosis?", "options": [{"label": "A", "text": "Acalculous Cholecystitis", "correct": true}, {"label": "B", "text": "Cholecystitis", "correct": false}, {"label": "C", "text": "Cholangitis", "correct": false}, {"label": "D", "text": "Choledocholithiasis", "correct": false}], "correct_answer": "A. Acalculous Cholecystitis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Acalculous Cholecystitis The patient is suffering from Acalculous cholecystitis. This is a rare ischemic type of cholecystitis with no gallstones forming. It occurs predominantly in immunosuppressed people (in this case, the patient suffers from AIDS). It can also occur due to the chemical nature of the bile acids. Acalculous cholecystitis is diagnosed by an optimistic Murphy’s sign and right upper shoulder pain, followed by abdominal sonography to rule out gallstones. The symptoms include bloating, nausea, vomiting, chills, fever, sweating, abdominal cramping, and yellow skin and eyes. Hence, it is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Cholecystitis is the inflammation of the gall bladder due to obstruction of the biliary apparatus by gallstones and infection. Murphy’s sign is positive, and right upper shoulder pain is elicited due to referred pain by the phrenic nerve. Since gallstones are present, it is the wrong answer. Option: C. Cholangitis is the inflammation of the whole biliary apparatus. Bacterial infections cause it and are usually acute. It can be chronic in some cases. Murphy’s sign is negative for cholangitis. Hence, it is the wrong answer. Option: D. Choledocholithiasis is the presence of gallstones containing calcium in the common bile duct. Gallstones are usually formed in the gallbladder. It causes obstructive jaundice, pain, fever, and clay-colored stools. Hence, it is the wrong answer.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 15 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which of the following structures pass the through sinus of Morgagni:", "options": [{"label": "A", "text": "Palatoglossus", "correct": false}, {"label": "B", "text": "Palatopharyngeus", "correct": false}, {"label": "C", "text": "Tensor tympani", "correct": false}, {"label": "D", "text": "Levator veli palatini muscle", "correct": true}], "correct_answer": "D. Levator veli palatini muscle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Levator veli palatini muscle Structures passing through the sinus of Morgagni Auditory tube Levator veli palatini muscle Ascending palatine artery Palatine branch of ascending pharyngeal artery</p>\n<p><strong>Highyeild:</strong></p><p>Structures passing between superior and middle constricto r Glossopharyngeal nerve Stylopharyngeus muscle Structures pass between the middle and inferior constrictor Internal laryngeal nerve Superior laryngeal vessels Structures pass below inferior constrictor Recurrent laryngeal nerve Inferior laryngeal vessels Schematic coronal section through the pharynx, showing the gaps between pharyngeal muscles and the structures related to them</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Palatoglossus Palatopharyngeus Tensor tympani Only one muscle, i.e. Levator veli palatini muscle passes through the sinus of Morgagni so options A, B and, C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The large gap between the upper concave border of the superior constrictor and the base of the skull is semilunar and is known as the sinus of Morgagni. It is closed by the upper strong part of the pharyngobasilar fascia</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Killian's dehiscence is a part of the:", "options": [{"label": "A", "text": "Nasopharynx", "correct": false}, {"label": "B", "text": "Oropharynx", "correct": false}, {"label": "C", "text": "Cricopharyngeus", "correct": true}, {"label": "D", "text": "Stylopharyngeus", "correct": false}], "correct_answer": "C. Cricopharyngeus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cricopharyngeus Killian's dehiscence (also known as Killian's triangle) is a triangular area in the wall of the pharynx between the cricopharyngeus and thyropharyngeus which are the two parts of the inferior constrictors.</p>\n<p><strong>Highyeild:</strong></p><p>Killian’s Dehiscence In the posterior wall of the pharynx, the lower part of the thyropharyngeus is a single sheet of muscle, not overlapped internally by the superior and middle constrictors. This weak part lies below the level of the vocal folds or upper border of the cricoid lamina and is limited inferiorly by the thick cricopharyngeal sphincter. This area is known as Killian’s dehiscence. Pharyngeal diverticula are formed by an outpouching of the dehiscence. It represents a potentially weak spot where a pharyngoesophageal diverticulum ( Zenker's diverticulum ) is more likely to occur. Killian’s Dehiscence</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Nasopharynx Oropharynx Stylopharyngeus Killian's dehiscence (also known as Killian's triangle) is a triangular area in the wall of the pharynx between the cricopharyngeus and thyropharyngeus which are the two parts of the inferior constrictors, therefore the above options are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>A similar triangular area between circular fibers of the cricopharyngeus and longitudinal fibers of the esophagus is Lamier's triangle or Lamier-hackermann's area.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Choose the incorrect statement regarding the marked muscle in the given picture:", "options": [{"label": "A", "text": "Forms anterior relation of palatine tonsil", "correct": true}, {"label": "B", "text": "Supplied by the cranial root of the accessory nerve via the pharyngeal plexus", "correct": false}, {"label": "C", "text": "Attaches to the posterior border of the lamina of thyroid cartilage", "correct": false}, {"label": "D", "text": "Raises the walls of the pharynx", "correct": false}], "correct_answer": "A. Forms anterior relation of palatine tonsil", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/questionImage-1707906772870-DMA017003.jpg"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Forms anterior relation of palatine tonsil The muscle marked in the given image is one of the common muscles of the palate and pharynx i.e. Which originates from palatine aponeurosis and inserts on the posterior border of the thyroid lamina & some fibers on the pharyngeal raphe. During deglutition, muscle helps in elevating Pharynx and larynx. All muscles of the Palate (including the one in pic) are supplied by Cranial XI via the pharyngeal plexus except Tensor veli palatini (V3 nerve). This muscle forms the POSTERIOR pillar of the palatine tonsil ( the Anterior pillar is by palatoglossus). This muscle forms the POSTERIOR pillar of the palatine tonsil ( The anterior pillar is by palatoglossus).</p>\n<p><strong>Highyeild:</strong></p><p>All the constrictors of the pharynx are inserted into a median raphe on the posterior wall of the pharynx. The upper end of the raphe reaches the base of the skull where it is attached to the pharyngeal tubercle on the basilar part of the occipital bone.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:B. Supplied by the cranial root of accessory nerve via pharyngeal plexus All muscles of the Palate (including the one in pic) are supplied by Cranial XI via the pharyngeal plexus except Tensor veli palatini (V3 nerve). Option:C. Attaches to the posterior border of the lamina of thyroid cartilage PALATOPHARYNGEUS, muscle originates from palatine aponeurosis and inserts on the posterior border of the thyroid lamina & some fibers on the pharyngeal raphe. Option:D. Raises the walls of the pharynx During the deglutition Palatopharyngeus muscle helps in elevating Pharynx and larynx.</p>\n<p><strong>Extraedge:</strong></p><p>The pharynx has three muscles that run longitudinally. The stylopharyngeus arises from the styloid process. It passes through the gap between the superior and middle constrictors to run downwards on the inner surface of the middle and inferior constrictors. The fibers of the palatopharyngeus descend from the sides of the palate and run longitudinally on the inner aspect of the constrictors. The salpingopharyngeus descends from the auditory tube to merge with the palatopharyngeus</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You use a cotton swab to obtain specimens for culture on a 14-year-old female patient who has complaints of a severe sore throat. As you lightly touch the pharyngeal wall with the cotton swab, the patient gags. What is the location of neuronal cell bodies innervating pharyngeal constrictor muscles involved in the gag reflex?", "options": [{"label": "A", "text": "Abducens Nucleus", "correct": false}, {"label": "B", "text": "Ambiguus nucleus", "correct": true}, {"label": "C", "text": "Dorsal motor nucleus of the vagus", "correct": false}, {"label": "D", "text": "Facial nucleus", "correct": false}], "correct_answer": "B. Ambiguus nucleus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ambiguus nucleus Motor innervation of the pharyngeal constrictor muscles is derived from the ambiguus nucleus in the medulla oblongata. These motor fibers reach the constrictor muscles via the vagus nerve.</p>\n<p><strong>Highyeild:</strong></p><p>The nucleus ambiguus is the location of cell bodies of motor nerves that innervate the ipsilateral muscles of the soft palate, pharynx, larynx, and upper esophagus and are mainly responsible for swallowing and speaking.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options :- Option: A . The abducens nucleus provides motor innervation to the lateral rectus muscle of the eye. Option: C. The dorsal motor nucleus of the vagus provides preganglionic parasympathetic innervation for the organs of the thorax and abdomen. Option: D. The facial nucleus sends motor innervation to the muscles of facial expression and the stapedius. The hypoglossal nucleus innervates the muscles of the tongue.</p>\n<p><strong>Extraedge:</strong></p><p>Lesions of nucleus ambiguus result in nasal speech, dysphagia, dysphonia, and deviation of the uvula toward the contralateral side. Preganglionic parasympathetic to the heart also flow through the external formation of the nucleus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 45-year-old lady was admitted to the emergency department with a fever of 4 days’ duration. An infection that is spreading from the retropharyngeal space to the posterior mediastinum is suspected. Between which of the following fascial layers is the infection most likely located?", "options": [{"label": "A", "text": "Between alar and prevertebral", "correct": false}, {"label": "B", "text": "Between alar and pretracheal", "correct": false}, {"label": "C", "text": "Between pretracheal and prevertebral", "correct": false}, {"label": "D", "text": "Between buccopharyngeal and alar fascia", "correct": true}], "correct_answer": "D. Between buccopharyngeal and alar fascia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Between buccopharyngeal and alar fascia The retropharyngeal space (RPS) is bordered by the following fascias: Buccopharyngeal fascia: The anterior boundary of the RPS Prevertebral fascia: The posterior boundary of the RPS Carotid sheath: The lateral boundary of the RPS Alar fascia: Divides the RPS into the true retropharyngeal space and the danger space. The RPS is a deep compartment in the neck that extends from the base of the skull to the mediastinum. It's located behind the esophagus and pharynx, and in front of the prevertebral muscles. The posterior extent of the retropharyngeal space can also be confusing. Between the visceral (buccopharyngeal) and prevertebral fascia, there are two spaces subdivided by a thin membrane known as the alar fascia. The anterior space is the \"true\" retropharyngeal while the posterior one is the danger space</p>\n<p><strong>Highyeild:</strong></p><p>Danger space of the neck is bounded at the top by the skull base, at the front by the alar fascia, and behind by the prevertebral fascia. It comes to an end at the level of the diaphragm. The retropharyngeal space is found anterior to the danger space, between the alar fascia and buccopharyngeal fascia. There exists a midline raphe in this space so some infections of this space appear unilateral. The retropharyngeal space</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options B, and C. Attachments of the alar fascia to the retropharyngeal fascia result in the separation of the pretracheal space from the retropharyngeal space. The pretracheal fascia encloses the trachea and larynx, whereas the buccopharyngeal fascia invests the superior pharyngeal constrictor and buccinator muscles. Option A. Between alar and prevertebral Danger space of the neck is bounded at the top by the skull base, at the front by the alar fascia, and behind by the prevertebral fascia. It comes to an end at the level of the diaphragm.</p>\n<p><strong>Extraedge:</strong></p><p>The danger space or alar space , is a region of the neck. The common name originates from the risk that an infection in this space can spread directly to the thorax, and, due to being a space continuous on the left and right, can furthermore allow infection to spread easily to either side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 55-year-old hypertensive lady is admitted to the emergency department after an episode of projectile vomiting, an aneurysm in the region between the posterior cerebral artery and superior cerebellar artery is detected. Which of the following nerves will most likely be compressed from the aneurysm?", "options": [{"label": "A", "text": "Trochlear", "correct": false}, {"label": "B", "text": "Abducens", "correct": false}, {"label": "C", "text": "Oculomotor", "correct": true}, {"label": "D", "text": "Vagus", "correct": false}], "correct_answer": "C. Oculomotor", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Oculomotor The oculomotor nerve passes between the posterior cerebral artery (PCA) and the superior cerebellar artery near the junction of the midbrain and pons.</p>\n<p><strong>Highyeild:</strong></p><p>Oculomotor compression causes Oculomotor nerve [III] Dilated pupil, ptosis, loss of normal pupillary reflex, eye moves down inferiorly and laterally (down and out) Pressure from an aneurysm arising from the posterior communicating, posterior cerebral, or superior cerebellar artery; pressure from a herniating cerebral uncus (false localizing sign); cavernous sinus mass or thrombosis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Although the trochlear nerve could be compressed by the superior cerebellar artery, it would not likely be damaged by an aneurysm of the PCA. Option B, D:The abducens nerve is located in the pons, and the vagus is situated near the postolivary sulcus in the medulla. Neither of these nerves is likely to be compressed by the arteries mentioned here due to their more distal location.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 40-year-old woman presents to the OPD complaining of unilateral neck pain, sore throat, and ear pain. Radiographic examination reveals long styloid processes, suggestive of Eagle’s syndrome. Which of the following nerves is most likely affected by Eagle’s syndrome in this patient?", "options": [{"label": "A", "text": "Vagus", "correct": false}, {"label": "B", "text": "Facial", "correct": false}, {"label": "C", "text": "Glossopharyngeal", "correct": true}, {"label": "D", "text": "Hypoglossal", "correct": false}], "correct_answer": "C. Glossopharyngeal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Glossopharyngeal The glossopharyngeal nerve (CN IX) enters the posterior oropharynx by coursing between the stylohyoid ligament and the stylopharyngeus muscle. Calcification of the stylohyoid ligament can readily affect this nerve by irritation or compression. The glossopharyngeal nerve carries sensory nerve fibers from the posterior third of the tongue and the pharynx. A lesion of this nerve could cause loss of both general sensation and taste sensation from the posterior third of the tongue. The glossopharyngeal nerve (CN IX) coursing between the stylohyoid ligament and the stylopharyngeus muscle.</p>\n<p><strong>Highyeild:</strong></p><p>Eagle syndrome (also termed stylohyoid syndrome , or styloid–carotid artery syndrome ) is an uncommon condition commonly characterized by sudden, sharp nerve-like pain in the jaw bone and joint, back of the throat, and base of the tongue, triggered by swallowing, moving the jaw, or turning the neck. The condition is caused by an elongated or misshapen styloid process (the slender, pointed piece of bone just below the ear) and/or calcification of the stylohyoid ligament, either of which interferes with the functioning of neighboring regions in the body, such as the glossopharyngeal nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options A, B, and D. The other nerves listed are not in close proximity to the styloid process or stylohyoid ligament.</p>\n<p><strong>Extraedge:</strong></p><p>Vascular Eagle syndrome, the elongated styloid process comes in contact with the internal carotid artery below the skull. In these cases, turning the head can cause compression of the artery or a tear inside the blood vessel, which restricts blood flow and can potentially lead to a transient ischemic attack or stroke. Sometimes, compression of the internal jugular vein can also occur and might lead to increased intracranial pressure.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The right costophrenic line extends up to the level of which rib in the mid-axillary line?", "options": [{"label": "A", "text": "6th", "correct": false}, {"label": "B", "text": "8th", "correct": false}, {"label": "C", "text": "10th", "correct": true}, {"label": "D", "text": "12th", "correct": false}], "correct_answer": "C. 10th", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>10th The costodiaphragmatic recess , also called the Costophrenic break, is the posterolateral fringe of the pleural space, a potential length around the lung inside the pleural cavity. It is located at the acutely angled junction (\"reflection\") between the costal and diaphragmatic parietal pleura and is interpreted two-dimensionally on plain X-rays as the costophrenic angle . It measures approximately 5 cm (2.0 in) vertically and extends from the eighth to the tenth rib along the mid-axillary line. Costophrenic recess</p>\n<p><strong>Highyeild:</strong></p><p>The function of Costophrenic Recess The lungs expand into this recess during forced inspiration; however, the break never gets filled. During expiration, it contains nothing apart from the gravitated serous fluid.</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options: Option A: 6th Option B: 8th- Costophrenic angle crosses the eighth rib in the midclavicular line. Option D: 12th rib The costovertebral angle (CVA) is located on your back at the bottom of your ribcage at the 12th rib. It's the 90-degree angle formed between the curve of that rib and your spine.</p>\n<p><strong>Extraedge:</strong></p><p>Pleural effusion fluid often builds up in the costophrenic angle (due to gravity). This can push the lung upwards, resulting in \"blunting\" of the costophrenic angle. The posterior angle is the deepest. Obtuse angulation is a sign of disease. A chest X-ray is the first test to confirm the pleural fluid's presence. The lateral upright chest X-ray should be examined when a pleural effusion is suspected. In an upright X-ray, 75 mL of fluid blunts the posterior costophrenic angle. Blunting the lateral costophrenic angle usually requires about 175 mL but may take as much as 500 mL. More significant pleural effusions opacify portions of the hemithorax and may cause a mediastinal shift; flows> 4 L may cause complete opacification of the hemithorax and mediastinal shift to the contralateral side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 50-year-old chronic smoker presented with cough, hemoptysis, and unexplained weight loss. CT scan revealed a tumor in the right lung invading the mediastinal pleura. The patient will likely experience referred pain in which of the following regions?", "options": [{"label": "A", "text": "Side of Neck", "correct": true}, {"label": "B", "text": "Anterolateral thoracic wall", "correct": false}, {"label": "C", "text": "The medial part of the arm", "correct": false}, {"label": "D", "text": "Abdominal wall", "correct": false}], "correct_answer": "A. Side of Neck", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Side of Neck The parietal pleura is pain sensitive. The coastal and peripheral parts of the diaphragmatic pleurae are supplied by the intercostal nerves The mediastinal pleura and central part of the diaphragmatic pleurae are supplied by the phrenic nerves (C4). The pain of the c4 dermatome is localized inside the neck</p>\n<p><strong>Highyeild:</strong></p><p>Dermatome distribution of neck and upper limb</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options :- Option B -Anterolateral Thoracic Wall innervated by intercostal nerves Option C -Medial Part of the arm innervated by the medial cutaneous nerve of the arm Option D -Abdominal Wall - Innervated by thoracoabdominal, lateral cutaneous, subcostal, iliohypogastric, and ilioinguinal nerves</p>\n<p><strong>Extraedge:</strong></p><p>The mediastinal part of the parietal pleura represents the lateral boundary of the mediastinum and forms a continuous covering above the level of the hilum of the lung, from the sternum anteriorly to the vertebral column posteriorly. On the right, it covers the right brachio- cephalic vein, the upper part of the superior vena cava, the terminal part of the azygos vein, the right phrenic and vagus nerves, the trachea, and the esophagus. On the left, it covers the aortic arch, left phrenic and vagus nerves, left brachiocephalic, and left superior intercostal veins.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A young man is rushed to the emergency department after suffering a stab wound over the chest wall. The entry wound is present on the left side in the midclavicular line. The lung is likely not to be injured if the entry wound is below which level?", "options": [{"label": "A", "text": "12th rib", "correct": false}, {"label": "B", "text": "10th rib", "correct": false}, {"label": "C", "text": "8th rib", "correct": true}, {"label": "D", "text": "6th rib", "correct": false}], "correct_answer": "C. 8th rib", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>8th rib The visceral pleura is continuous with the parietal pleura at the hilum of each lung, where structures enter and leave the organ . The visceral pleura is firmly attached to the surface of the lung, including both opposed surfaces of the fissures that divide the lungs into lobes. The lower border of each visceral pleura lies two ribs higher than the parietal pleural reflection. Reflection of Parietal Pleura Inferiorly, the costal pleura reflects onto the diaphragm above the costal margin. The pleural cavity extends inferiorly to approximately rib VIII in the midclavicular line. So the correct answer is Option C. In the midaxillary line, it extends to rib X. From this point, the inferior margin courses somewhat horizontally, crossing ribs XI and XII to reach vertebra TXII. From the mid clavicular line to the vertebral column, the inferior boundary of the pleura can be approximated by a line that runs between rib VIII, rib X, and vertebra TXII.</p>\n<p><strong>Highyeild:</strong></p><p>Apices of the lung extend about three centimeters above the medial third of the clavicles and then project inferolateral to the junction of the medial and middle thirds of the clavicle. Anteriorly, the hila lies at the level of costal cartilages 3-4; this corresponds to vertebral levels T5-7. The inferior margins of the lung are: T6 - midclavicular line T8 - mid-axillary line T10 - posteriorly At each point, the parietal pleural reflections sit inferiorly by approximately 2 ribs. However, this level varies with the respiratory phase. Lower margin of lung and Pleura</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. 12th rib The entry wound mentioned in the question is present on the left side in the midclavicular line. The pleural cavity extends inferiorly to approximately rib VIII in the midclavicular line. Option B. 10th rib In the midaxillary line, the pleura extends to rib X. From this point, the inferior margin courses somewhat horizontally, crossing ribs XI and XII to reach vertebra TXII. Option D. 6th rib The lung crosses the sixth rib in the midclavicular line.</p>\n<p><strong>Extraedge:</strong></p><p>The anterior margins of the parietal pleura are different on each side and largely follow the lines of parietal pleural reflection: on the right: deep to the right side of the sternum between the second and fourth costal cartilages inferolateral to the level of the deep surface of the sixth right intercostal cartilage on the left: deep to the sternum near the midline inferiorly between the levels of costal cartilages 2 and 4 displaced laterally and more obliquely than the left side to a point about 3 cm lateral to the left sternal edge at the upper margin of the sixth costal cartilage The space created by the lateral deviation of the pleura and lung on the left side is termed the cardiac notch.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You are asked to mark the oblique fissure of the lung on a cadaver. Which landmarks will not touch the line while drawing surface markings for this fissure?", "options": [{"label": "A", "text": "6th Intercostal Space", "correct": false}, {"label": "B", "text": "5th rib", "correct": false}, {"label": "C", "text": "7th rib", "correct": false}, {"label": "D", "text": "4th costal cartilage", "correct": true}], "correct_answer": "D. 4th costal cartilage", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>4th costal cartilage The right lung is divided into three lobes (upper, middle, and lower) by two fissures (oblique and horizontal). The left lung is divided into two lobes by the oblique fissure. The oblique fissures (also called the major fissures or greater fissures ) are bilateral structures in both lungs separating the lung lobes. Right oblique fissure The superior part of the right oblique fissure separates the right upper lobe from the right lower lobe and the inferior part separates the right middle lobe from the right lower lobe. Its approximate position can be marked by a curved line on the thoracic wall that begins roughly at the spinous process of the T4 level of the thoracic spine, then crosses the fifth intercostal space laterally, and follows the contour of the right 6th rib anteriorly. Left oblique fissure The left oblique fissure separates the left upper lobe from the left lower lobe. Its approximate position can be marked by a curved line on the thoracic wall that begins between the spinous processes of vertebrae T3 and T4, then crosses the fifth intercostal space laterally, and follows the contour of the 6th rib anteriorly.</p>\n<p><strong>Highyeild:</strong></p><p>A horizontal fissure of the lung is a recess in the parenchyma of the right superior lobe of the lung. Its surface markings are from the right fourth costal cartilage level horizontally to a junction with the oblique fissure at approximately the midaxillary line in the fifth intercostal space. It divides up the right-sided volume of lung tissue above the oblique fissure into: right superior lobe, above the fissure right middle lobe, below the fissure The horizontal fissure is represented by a line joining: A point on the anterior border of the right lung at the level of the fourth costal cartilage. A second point on the fifth rib in the midaxillary line. Surface projection of lung and pleura</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. 6th Intercostal Space Option B. 5th rib Option C. 7th rib The oblique fissure can be drawn by joining: A point 2 cm lateral to the third thoracic spine/ posterior end of the 4th rib. Option B -Another point on the 5th rib in the midaxillary line Options A & C -A third point on the 6th costal cartilage/ 7th rib (7.5 cm from the median plane).</p>\n<p><strong>Extraedge:</strong></p><p>The oblique fissures are highly variable and may be incomplete or absent, thus complicating the identification of various pathological processes. In the majority of cases, the left oblique fissure is located at a higher level and courses more vertically than the right oblique fissure. Both oblique fissures can present as incomplete fissures (48% on the right compared with 43% on the left). The absence of the oblique fissure is rare and occurs in <1% of the population.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You are asked to do thoracentesis for a patient with mild pleural effusion on the left side. You are being cautious while inserting a needle in the left mid-axillary line of the patient. You would not insert the needle below which is level so as not to damage the surrounding structures?", "options": [{"label": "A", "text": "6th rib", "correct": false}, {"label": "B", "text": "10th rib", "correct": true}, {"label": "C", "text": "8th rib", "correct": false}, {"label": "D", "text": "12th rib", "correct": false}], "correct_answer": "B. 10th rib", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>10th rib The lower extension of the parietal pleura in the mid-axillary line is the 10th rib, hence don’t insert a needle below this. The inferior margin, or the costodiaphragmatic line of pleural reflection, passes laterally from the lower limit of its anterior margin so that it crosses the 8th rib in the midclavicular line. 10th rib in the midaxillary line. 12th rib at the lateral border of the sacrospinalis muscle.</p>\n<p><strong>Highyeild:</strong></p><p>Thoracocentesis , Pleural tap , Needle thoracostomy , or Needle decompression (often used term) is an invasive medical procedure to remove fluid or air from the pleural space for diagnostic or therapeutic purposes. The recommended location varies depending on the source. Some sources recommend the midaxillary line in the eighth, ninth, or tenth intercostal space. The procedure should be performed under ultrasound guidance, which has been shown to reduce complications. Tension pneumothorax is a medical emergency that requires emergent needle decompression before a chest tube is placed. Thoracentesis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A . 6th rib Option C. 8th rib Option D. 12th rib Options A , B, and C are incorrect because the lower extension of the parietal pleura in the mid-axillary line is the 10th rib, hence needle should not be inserted below this level.</p>\n<p><strong>Extraedge:</strong></p><p>The most common causes of pleural effusions are cancer, congestive heart failure, pneumonia, and recent surgery. In countries like India, where tuberculosis is common, this is also a common cause of pleural effusions. When the cardiopulmonary status is compromised (i.e. when the fluid or air has its repercussions on the function of the heart and lungs), due to air (significant pneumothorax), fluid (pleural fluid), or blood (hemothorax) outside the lung, then this procedure is usually replaced with tube thoracostomy, the placement of a large tube in the pleural space.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are true about pleural recesses except:", "options": [{"label": "A", "text": "The costomediastinal recess lies anteriorly,", "correct": false}, {"label": "B", "text": "The costomediastinal recess is filled up by the anterior margin of the lungs even during quiet breathing", "correct": false}, {"label": "C", "text": "The costodiaphragmatic recess lies inferiorly between the costal and diaphragmatic pleura.", "correct": false}, {"label": "D", "text": "Costodiaphragmatic recesses are obvious only in inspiration and not in deep expiration.", "correct": true}], "correct_answer": "D. Costodiaphragmatic recesses are obvious only in inspiration and not in deep expiration.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Costodiaphragmatic recesses are obvious only in inspiration and not in deep expiration. The costodiaphragmatic recess , also called the costophrenic recess, is the posterolateral fringe of the pleural space, a potential space around the lung inside the pleural cavity . It is located at the acutely angled junction (\"reflection\") between the costal and diaphragmatic parietal pleura and is interpreted two-dimensionally on plain X-rays as the costophrenic angle. It measures approximately 5 cm (2.0 in) vertically and extends from the eighth to the tenth rib along the mid-axillary line. During inspiration, the lungs expand into Costodiaphragmatic recesses. So these recesses are obvious only in the expiration and not in deep inspiration.</p>\n<p><strong>Highyeild:</strong></p><p>Pleural effusion collects in the Costodiaphragmatic recess when in a standing position and is present on plain X-rays as \"blunting\" of the costophrenic angle. A thoracocentesis (pleural tap) is often performed here while a patient is in full expiration because of less risk of puncturing the lungs and thereby causing pneumothorax.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Costomediastinal recess lies anteriorly. The costomediastinal recess is a potential space at the border of the mediastinal pleura and the costal pleura. The costomediastinal recess lies anteriorly behind the sternum and costal cartilages, between the costal and mediastinal pleura, particularly about the cardiac notch of the left lung. Option B. Costomediastinal recess is filled up by the anterior margin of the lungs even during quiet breathing. The costomediastinal recess assists lung expansion during deep inspiration, although its role is not as significant as the costodiaphragmatic recess, which has a greater volume. The lung expands into the Costomediastinal recess even during shallow inspiration. The costomediastinal recess is most evident in the cardiac notch of the left lung. Option C. Costodiaphragmatic recess lies inferiorly between the costal and diaphragmatic pleura. The costodiaphragmatic/ costovertebral recess lies inferiorly between the costal and diaphragmatic pleura. Vertically, it measures about 5 cm and extends from the eighth to tenth ribs along the midaxillary line.</p>\n<p><strong>Extraedge:</strong></p><p>Pleural effusion fluid often builds up in the costophrenic angle (due to gravity). This can push the lung upwards, resulting in \"blunting\" of the costophrenic rise. The posterior angle is the deepest. Obtuse angulation is a sign of disease. Costodiaphragmatic and Costomediastinal recess</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "What is the Superolateral boundary of the popliteal fossa?", "options": [{"label": "A", "text": "Semimembranosus", "correct": false}, {"label": "B", "text": "The lateral head of the gastrocnemius", "correct": false}, {"label": "C", "text": "The medial head of the gastrocnemius", "correct": false}, {"label": "D", "text": "Biceps femoris", "correct": true}], "correct_answer": "D. Biceps femoris", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Biceps femoris The biceps femoris -forms the Superolateral boundary of the popliteal fossa.</p>\n<p><strong>Highyeild:</strong></p><p>Boundaries of Popliteal fossa Content of Popliteal Fossa</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - Semimembranosus and semitendinosus- form the proximo medial boundary. Option B - Lateral head of gastrocnemius form disto lateral boundary. Option C - Medial head of gastrocnemius form disto medial boundary.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among these forms the roof of the popliteal fossa?", "options": [{"label": "A", "text": "Fascia Musculorum", "correct": true}, {"label": "B", "text": "The lateral head of the gastrocnemius", "correct": false}, {"label": "C", "text": "The medial head of the gastrocnemius", "correct": false}, {"label": "D", "text": "Biceps femoris", "correct": false}], "correct_answer": "A. Fascia Musculorum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fascia Musculorum The deep fascia (fascia Musculorum) acts as the roof of the fossa and is continuous with the fascia lata proximally and the deep fascia of the leg distally . It is a dense layer strongly reinforced by transverse fibres and is often perforated by the short saphenous vein and medial and lateral sural cutaneous nerves</p>\n<p><strong>Highyeild:</strong></p><p>Contents in Roof of Popliteal fossa</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B - Lateral head of the gastrocnemius forms the inferolateral boundary of the popliteal fossa. Option C - Medial head of the gastrocnemius forms the inferomedial boundary of the popliteal fossa. Option D - Biceps femoris forms the proximolateral boundary of the popliteal fossa.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following does not form the floor of the popliteal fossa?", "options": [{"label": "A", "text": "The popliteal surface of femur", "correct": false}, {"label": "B", "text": "Oblique popliteal ligament", "correct": false}, {"label": "C", "text": "The posterior aspect of the proximal tibia is covered by the popliteus and its fascia.", "correct": false}, {"label": "D", "text": "Fascia Musculorum", "correct": true}], "correct_answer": "D. Fascia Musculorum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fascia Musculorum The deep fascia (fascia Musculorum) acts as the roof of the fossa and is continuous with the fascia lata proximally and the deep fascia of the leg distally. It is a dense layer strongly reinforced by transverse fibres and is often perforated by the short saphenous vein and medial and lateral sural cutaneous nerves .</p>\n<p><strong>Random:</strong></p><p>The anterior boundary (or floor) of the fossa is formed, in proximodistal sequence, by the ' Option A - Popliteal surface of the femur. Option B - The oblique popliteal ligament (overlying the posterior surface of the knee joint capsule). Option C - The popliteus and its deep fascia cover the posterior aspect of the proximal tibia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "When the knee is flexed against resistance, the tendon of which muscle is felt lateral to popliteal fossa?", "options": [{"label": "A", "text": "Semimembranosus", "correct": false}, {"label": "B", "text": "Semitendinosus", "correct": false}, {"label": "C", "text": "Biceps femoris", "correct": true}, {"label": "D", "text": "Gracilis", "correct": false}], "correct_answer": "C. Biceps femoris", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Biceps femoris When the knee is flexed against resistance, the tendon of biceps femoris can be felt lateral to the popliteal fossa. Boundaries of Popliteal fossa</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A -The semimembranosus tendon is palpable between lateral and medial (and also by deep pressure from a ‘pincer’ grip beyond their margins). Option B - Semitendinosus - medial to the popliteal fossa, the tendons of semitendinosus stand out sharply. Option D - Gracilis-Medial to the popliteal fossa, the tendons of gracilis present which is the more medial than semitendinosus</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is false regarding the popliteal fossa?", "options": [{"label": "A", "text": "The popliteal fossa is approximately 2.5 cm wide.", "correct": false}, {"label": "B", "text": "Distally, its contents are protected and hidden by the heads of gastrocnemius, which contact each other.", "correct": false}, {"label": "C", "text": "The common fibular nerve descends centrally immediately medial to the tendon of the biceps femoris.", "correct": true}, {"label": "D", "text": "The tibial nerve descends centrally immediately anterior to the deep fascia.", "correct": false}], "correct_answer": "C. The common fibular nerve descends centrally immediately medial to the tendon of the biceps femoris.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The common fibular nerve descends centrally immediately medial to the tendon of the biceps femoris. The t ibial nerve descends centrally immediately anterior to the deep fascia, crossing the vessels posteriorly from lateral to medial. The common fibular nerve descends laterally immediately medial to the tendon of biceps femoris.</p>\n<p><strong>Highyeild:</strong></p><p>Contents of Popliteal Fossa</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - Popliteal fossa is approximately 2.5 cm wide. Option B - Distally, its contents are protected and hidden by the heads of gastrocnemius, which contact each other. Option D - The tibial nerve descends centrally immediately anterior to the deep fascia, crossing the vessels posteriorly from lateral to medial.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Duplicated popliteal veins located on which side of the popliteal artery?", "options": [{"label": "A", "text": "Lateral to Artery", "correct": false}, {"label": "B", "text": "Medially", "correct": false}, {"label": "C", "text": "Posteriorly", "correct": false}, {"label": "D", "text": "Vein are on both sides of the artery", "correct": true}], "correct_answer": "D. Vein are on both sides of the artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Vein are on both sides of the artery The popliteal vein may be duplicated, so that the artery lies between the veins, which are usually bridged by connecting channels. When the popliteal vessels enter the proximal region of the popliteal fossa, they maintain a side-by-side relationship, which shifts to an over-under relationship as they descend through the fossa and are held together by dense areolar tissue within the fossa.</p>\n<p><strong>Highyeild:</strong></p><p>The popliteal vein is generally located posterior to the artery. Proximally, the vein lies lateral to the artery, crossing to its medial side distally. At times, the popliteal vein may be duplicated, so that the artery lies between the veins, which are usually bridged by connecting channels. An articular branch from the obturator nerve descends along the artery to the knee. Six or seven popliteal nodes are embedded in the fat, one under the deep fascia near the termination of the short saphenous vein, one between the popliteal artery and knee joint, and the others intimate with the popliteal vessels.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - Proximally, the vein lies lateral to the artery. Option B - crossing to its medial side distally. Option D - The popliteal vein is generally located posterior to the artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Following are content of popliteal fossa except:", "options": [{"label": "A", "text": "Popliteal Artery", "correct": false}, {"label": "B", "text": "Popliteal vein", "correct": false}, {"label": "C", "text": "Tibial nerve", "correct": false}, {"label": "D", "text": "Deep fibular nerve", "correct": true}], "correct_answer": "D. Deep fibular nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deep fibular nerve Deep fibular nerve is not the content of fossa. Common fibular nerve is the content of fossa common fibular nerve bifurcate and gives rise to a deep nerve. Contents of Popliteal Fossa</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- The fossa contains the popliteal vessels, tibial and common fibular nerves, short saphenous vein, medial and lateral sural cutaneous nerves, posterior femoral cutaneous nerve, an articular branch of the obturator nerve, lymph nodes, fat and a variable number of bursae. Option A - Popliteal artery: deepest and give off genicular branches Option B - Popliteal vein: lies in between artery and tibial nerve Option C - Tibial nerve: most superficial giving off Sural nerve which descend to pierce the roof in the lateral fossa and join sural nerve</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "During the laparoscopic cholecystectomy in a 40-year-old female patient, accidentally, the hepatoduodenal ligament was clamped instead of the cystic artery. Which vessels would most likely be occluded in this iatrogenic injury?", "options": [{"label": "A", "text": "Superior Mesenteric Artery", "correct": false}, {"label": "B", "text": "Proper hepatic artery", "correct": true}, {"label": "C", "text": "Splenic artery", "correct": false}, {"label": "D", "text": "Common hepatic artery", "correct": false}], "correct_answer": "B. Proper hepatic artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Proper hepatic artery The proper hepatic artery is the only artery typically within the hepatoduodenal ligament and, therefore would be impeded. This artery lies within the right anterior free margin of Winslow's omental (or epiploic) foramen.</p>\n<p><strong>Highyeild:</strong></p><p>The hepatoduodenal ligament ends laterally as a free margin and serves as the anterior border of the omental foramen. E nclosed in this free edge are the hepatic artery proper, the bile duct, and the portal vein. Additionally, the right and left gastric vessels are between the layers of the lesser omentum near the lower curvature of the stomach. Hepatoduodenal ligament</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. The superior mesenteric artery branches from the abdominal aorta inferior to the hepatoduodenal ligament. Option C. The splenic artery runs behind the stomach and is not in the hepatoduodenal ligament. Option D. The common hepatic artery originates from the proper hepatic artery but does not run within the hepatoduodenal ligament.</p>\n<p><strong>Extraedge:</strong></p><p>The lesser omentum is a double-layered fold of the peritoneum between the stomach's lower curvature and the liver's inferior surface. The part of lesser omentum between stomach and the liver is called the hepatogastric ligament, and the part between the duodenum and the liver is called the hepatoduodenal ligament. The right free margin of the lesser omentum, where the anterior and posterior layers of peritoneum become continuous, forms the anterior boundary of the foramen epiploic. Along the lesser curvature of the stomach, the lesser omentum contains: Right and left gastric vessels and associated gastric Branches of the left gastric nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 58-year-old male alcoholic is admitted to the hospital after vomiting dark red blood (hematemesis). Endoscopy reveals ruptured esophageal varices, most likely resulting from portal hypertension. Which venous tributaries to the portal system anastomoses with caval veins cause the varices?", "options": [{"label": "A", "text": "Splenic", "correct": false}, {"label": "B", "text": "Left gastro-omental", "correct": false}, {"label": "C", "text": "Left gastric", "correct": true}, {"label": "D", "text": "Left hepatic", "correct": false}], "correct_answer": "C. Left gastric", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left gastric The left gastric vein carries blood from the stomach to the portal vein. At the esophageal-gastric junction, the left gastric vein (portal system) anastomoses with esophageal veins (canal system). High blood pressure in the portal system causes increased pressure in this anastomosis, causing the ruptured esophageal varices.</p>\n<p><strong>Highyeild:</strong></p><p>The lower end esophagus is one of the sites of portocaval anastomoses. Some esophageal veins drain into the left gastric vein and the portal vein. Other esophageal veins drain into hemiazygos, vena azygos, and superior vena cava. In liver cirrhosis, portal venous pressure is raised, leading to esophageal varices , which may rupture, leading to</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. The splenic vein and its tributaries carry blood away from the spleen and do not form a caval-portal anastomosis. Option B. The left gastro-omental vein accompanies the left gastro-omental artery and joins the splenic vein with no direct anastomosis with caval veins. Option D. The left hepatic vein is a caval vein and empties into the inferior vena cava.</p>\n<p><strong>Extraedge:</strong></p><p>The effects of portal hypertension are as follows. Congestive splenomegaly Ascites Collateral circulation through the portosystemic communications. It forms: Caput medusae around the umbilicus, which is of diagnostic value to the clinician Esophageal varices at the lower end of the esophagus may rupture and cause dangerous or even fatal haematemesis. Hemorrhoids i n the anal canal may be responsible for repeated bleeding felt per rectum.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 52-year-old man presents to the emergency department complaining of persistent severe right upper quadrant pain for the past 2 hours. During that period, he felt nauseated, was sweating profusely, and experienced pain in the posterior aspect of his right shoulder. The pain began shortly after a lunch consisting of “fast food.” Ultrasound examination reveals multiple stones in an inflamed gallbladder with a normal bile duct. Which spinal nerve segments are involved in the shoulder pain associated with cholecystitis?", "options": [{"label": "A", "text": "C3 To C5", "correct": false}, {"label": "B", "text": "C5 to C8", "correct": false}, {"label": "C", "text": "T1 to T4", "correct": false}, {"label": "D", "text": "T5 to T9", "correct": true}], "correct_answer": "D. T5 to T9", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>T5 to T9 Referred pain from cholecystitis is generally referred to the region of the inferior angle of the right scapula. These fibers are usually from T5 to T9. These sensory fibers for pain are stimulated by gallbladder inflammation because of the proximity of the adjacent structures.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. C3 to C5 sensory fibers innervate the shoulder area. Option B. The distribution of C5 to C8 is primarily to the upper limb, to the level of the hand; Option C. T1 to T4 distribution is to the upper thoracic wall and upper medial arm; T1 to T4 visceral fibers for pain is generally associated with referred pain from the heart.</p>\n<p><strong>Extraedge:</strong></p><p>Important sites of communication of portal and systemic veins: (1) Lower end of the esophagus, (2) around umbilicus, and (3) anal canal</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 55-year-old man is admitted to the hospital for his annual checkup. An ultrasound examination reveals a tumor that has incorporated the right common iliac artery and compressed the posterior vein. Doppler ultrasound studies give evidence of the development of a deep venous thrombosis that could block venous return from the left lower limb, causing ischemia and pain. Which of the following vessels is most likely to be involved in producing deep venous thrombosis?", "options": [{"label": "A", "text": "Inferior Vena Cava", "correct": false}, {"label": "B", "text": "Right renal vein", "correct": false}, {"label": "C", "text": "Left testicular vein", "correct": false}, {"label": "D", "text": "Left common iliac vein", "correct": true}], "correct_answer": "D. Left common iliac vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left common iliac vein The left common iliac vein lies posterior to the right common iliac artery. Compression of the vein in this location is a frequent cause of deep venous thrombosis of the left lower limb ; that is, the venous drainage of the lower limb is obstructed. This can cause extreme pain and ischemia of the limb, which, in some untreated cases, can lead to amputation of the stem or gangrene, leading to death. The inferior vena cava would not be compressed, for it has branched superior to the tumor's location.</p>\n<p><strong>Highyeild:</strong></p><p>The external iliac veins and internal iliac veins form common iliac veins . The left and right common iliac veins come together in the abdomen at the level of the fifth lumbar vertebra, forming the inferior vena cava. They drain blood from the pelvis and lower limbs. Both common iliac veins are accompanied along their course by common iliac arteries. Common iliac vein</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:-: Option A. The right common iliac vein passes freely about the pelvic brim after originating from the inferior vena cava. It would not be subjected to compression by the right common iliac artery. Option B. The renal veins would not be compromised because these veins extend from the kidneys to the inferior vena cava, quite far above the blockage. Option C. The testicular veins pass lateral to the area of obstruction, with the right gonadal vein passing superiorly to join the inferior vena cava and the left gonadal vein terminating in the left renal vein.</p>\n<p><strong>Extraedge:</strong></p><p>The inferior vena cava lies to the right of the vertebral column and penetrates the central tendon of the diaphragm at approximately vertebral level TVIII. A number of large vessels cross the midline to deliver blood from the left side of the body to the inferior vena cava. One of the most significant is the left renal vein, which drains the kidney, suprarenal gland, and gonad on the same side. Another is the left common iliac vein, which crosses the midline at approximately vertebral level Lumbar-V to join with its partner on the right to form the inferior vena cava. These veins drain the lower limbs, the pelvis, the perineum, and parts of the abdominal wall. Other vessels crossing the midline include the left lumbar veins, which drain the back and posterior abdominal wall on the left side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 51-year-old man complains of abdominal pain for a 2-month duration. A CT scan of the patient’s abdomen is shown. An angiogram indicates that several arteries of the gastrointestinal tract are occluded due to atherosclerosis, producing bowel ischemia. Which of the following arteries is most likely occluded in the CT scan?", "options": [{"label": "A", "text": "Middle Colic", "correct": false}, {"label": "B", "text": "Right colic", "correct": false}, {"label": "C", "text": "Left colic", "correct": true}, {"label": "D", "text": "Marginal", "correct": false}], "correct_answer": "C. Left colic", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681065338-QTDA008005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left colic The arrows in the CT scan point to the descending colon. Therefore, the left colic artery, which supplies the descending colon, is most likely occluded in the CT scan.</p>\n<p><strong>Highyeild:</strong></p><p>Left colic artery The left colic artery is a branch of the inferior mesenteric artery distributed to the descending colon and left part of the transverse colon. It ends by dividing into ascending and descending branches; the terminal branches of the two components form anastomoses with the middle colic artery and a sigmoid artery, respectively.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:-: Options A, B, and D. The middle colic, right colic, and ileocolic artery supply the ascending colon. The marginal artery provides an anastomosis between branches of the superior mesenteric artery and inferior mesenteric artery.</p>\n<p><strong>Extraedge:</strong></p><p>The left colic artery usually represents the dominant arterial supply to the left colic flexure . Branches Ascending branch The ascending branch passes the superior ward. It passes anterior to the (ipsilateral) psoas major muscle, gonadal vessels, ureter, and kidney and posterior to the inferior mesenteric vein. Its terminal branches form anastomoses with those of the middle colic artery; it also forms anastomoses with the descending branch (of the left colic artery). Descending branch The descending branch passes inferolateral. It forms anastomoses with the superior-most sigmoid artery and the ascending branch (of the left colic artery), thereby forming the colon's marginal artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A hard mass (a fecalith) in the ostium of a 27-year-old patient’s appendix had led to a local infection (appendicitis) with a slightly elevated temperature and a moderate increase in WBC count. The initial pain from the infection was dull and difficult to localize, but the patient placed his hand in the periumbilical area to indicate the general area of discomfort. The umbilicus region receives its sensory supply, classically, from which of the following spinal nerves?", "options": [{"label": "A", "text": "T7", "correct": false}, {"label": "B", "text": "T8", "correct": false}, {"label": "C", "text": "T10", "correct": true}, {"label": "D", "text": "T12", "correct": false}], "correct_answer": "C. T10", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>T10 The dermatome of spinal nerve level T10 crosses the story of the umbilicus ; Pain from appendicitis is most often perceived at first in the periumbilical region, reflecting the embryologic spinal nerve supply level to the appendix, which is from T10. When the appendix swells and ruptures and contacts the body wall, somatic sensory fibers of the adjacent body wall cause the apparent site of pain to shift to the lower right abdominal quadrant.</p>\n<p><strong>Highyeild:</strong></p><p>Appendicitis is inflammation of the appendix. Symptoms commonly include right lower abdominal pain, nausea, vomiting, and decreased appetite. However, approximately 40% of people do not have these typical symptoms. Severe complications of a ruptured appendix include widespread, painful inflammation of the inner lining of the abdominal wall and sepsis.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Dermatome of T7 is at the level of the xiphoid process Option B. T8 and T9 dermatomes lie between the preceding spinal nerve levels. Option D. T12 innervates the lowest portion of the rectus abdominis and overlying skin with motor and sensory supply, respectively.</p>\n<p><strong>Extraedge:</strong></p><p>The classic migration of Appendicitis pain may not be seen in children under three years. Pain from appendicitis may begin as dull pain around the navel. After several hours, the pain will usually transition towards the right lower quadrant, where it becomes localized. Symptoms include localized findings in the right iliac fossa. The abdominal wall becomes very sensitive to gentle pressure (palpation). There is a pain in the sudden release of deep tension in the lower abdomen (Blumberg's sign) . If the appendix is retrocausal (localized behind the cecum), even deep pressure in the right lower quadrant may fail to elicit tenderness (silent appendix). This is because the cecum, distended with gas, protects the inflamed appendix from pressure. Similarly, if the appendix lies entirely within the pelvis, there is typically a complete absence of abdominal rigidity. In such cases, a digital rectal examination elicits tenderness in the rectovesical pouch. Coughing causes point tenderness in this area (McBurney's point), called Dunphy's sign.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "If cirrhosis obstructs the portal circulation within the liver, portal blood could still be conveyed to the canal system via which of the following?", "options": [{"label": "A", "text": "Azygos and hemiazygos veins", "correct": true}, {"label": "B", "text": "Gonadal veins", "correct": false}, {"label": "C", "text": "Internal iliac veins", "correct": false}, {"label": "D", "text": "Splenic vein", "correct": false}], "correct_answer": "A. Azygos and hemiazygos veins", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Azygos and hemiazygos veins The esophageal venous plexus, which drains into the azygos and hemiazygos veins within the thorax, has anastomoses with branches of the left gastric vein. Thus, following blockage of the portal vein, portal blood may enter the superior vena cava via the azygos system.</p>\n<p><strong>Highyeild:</strong></p><p>Meaningful portocaval connections include the superior rectal vein with the middle and inferior rectal veins; paraumbilical veins and epigastric veins (engorgement of these vessels results in caput-medusae); and the colic and splenic veins with renal veins and veins of the posterior body wall.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Gonadal veins The gonadal veins exclusively drain the gonads (although in the female, the ovarian vein communicates with the uterovaginal plexus). These vessels have no anastomoses with portal veins. Option C. Internal iliac veins The internal iliac veins, which drain most of the pelvis and much of the inferior extremities, have no demonstrated portal anastomoses. Option D. Splenic vein The splenic vein is incorrect because it's in itself a component of the portal venous system.</p>\n<p><strong>Extraedge:</strong></p><p>The vesical venous plexus, which is situated well within the pelvis and drains the bladder and the prostate (or uterus and vagina) has no association with portal vessels. The azygos system of veins serves as an important anastomotic pathway capable of returning venous blood from the lower part of the body to the heart of the inferior vena cava is blocked. The gastroesophageal junction around the cardia of the stomach-where the left gastric vein and its tributaries form a portosystemic anastomosis with tributaries to the azygos system of veins of the canal system.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is responsible for the development of portal veins?", "options": [{"label": "A", "text": "A", "correct": false}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": true}], "correct_answer": "D. D", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681065372-QTDA008008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>D The portal vein is derived from right and left vitelline veins and anastomoses between them. A- Sinus venosus B - Cardinal vein C - Umbilical vein D - Vitelline vein Explanation: Before entering the sinus venosus, the Vitelline veins form a plexus around the duodenum and pass through the septum transversum. The liver cords growing into the septum interrupt the course of the veins, and an extensive vascular network, the hepatic sinusoids, forms. With the reduction of the left sinus horn, blood from the left side of the liver is rechanneled toward the right, resulting in an enlargement of the right vitelline vein (right hepatocardiac channel). Ultimately, the right hepatocardiac channel forms the hepatocardiac portion of the inferior vena cava. The proximal part of the left vitelline vein disappears. The anastomotic network around the duodenum develops into a single vessel, the portal vein. Stages of development of Portal vein</p>\n<p><strong>Highyeild:</strong></p><p>With the increase of the placental circulation, direct communication forms between the left umbilical vein and the right hepatocardiac channel, the ductus venosus . This vessel bypasses the sinusoidal plexus of the liver. After birth, the left umbilical vein and ductus venosus are obliterated, forming the ligamentum teres hepatitis and ligamentum venosum, respectively.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A- Sinus venosus – It forms the entry point for the venous system. Option B- Left common cardinal vein Option C- Left umbilical vein The source of development of the Portal vein is the left vitelline vein, so Options A,B, and C are all incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The superior mesenteric vein, which drains the primary intestinal loop, derives from the right vitelline vein. The distal portion of the left vitelline vein also disappears.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the below is true statements relations of portal vein?", "options": [{"label": "A", "text": "Origin is posterior to the head of the pancreas", "correct": false}, {"label": "B", "text": "Ascends behind the second part of duodenum", "correct": false}, {"label": "C", "text": "Ascends inside the hepatogastric ligament till the hilum of the liver", "correct": true}, {"label": "D", "text": "Forms posterior boundary of Epiploic foramen", "correct": false}], "correct_answer": "C. Ascends inside the hepatogastric ligament till the hilum of the liver", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ascends inside the hepatogastric ligament till the hilum of the liver Portal vein enters the right border of the lesser omentum (hepatoduodenal ligament) and ascends anterior to the omental foramen to reach the right end of the porta hepatis, where it divides into right and left main branches, which accompany the corresponding branches of the hepatic artery into the liver. In the lesser omentum, the hepatic portal vein lies posterior to both the bile duct and the hepatic artery. It is surrounded by the hepatic plexus and accompanied by lymphatics and some lymph nodes.</p>\n<p><strong>Highyeild:</strong></p><p>Portal vein is formed by joining Superior mesenteric & splenic veins behind the neck of the pancreas.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Origin is posterior to the head of the pancreas Portal vein is formed by joining the Superior mesenteric & splenic veins behind the neck of the Option B. Ascends behind the second part of the duodenum It ascends behind the first part of the duodenum in the lesser omentum / Hepato-gastric ligament with bile duct to right & hepatic artery to left. Option D. Forms posterior boundary of Epiploic foramen Portal vein forms the anterior boundary of Epiploic foramen. IVC forms its posterior boundary.</p>\n<p><strong>Extraedge:</strong></p><p>Portal vein receives various tributaries: posterior superior pancreaticoduodenal vein (through the posterior pancreaticoduodenal sulcus) inferior mesenteric vein (portomesenteric confluence) gastric veins (behind the first part of the duodenum) cystic veins (right branch of the portal vein) Sappey veins (left branch of the portal vein) The inferior mesenteric vein joins the splenic vein 40% of the time, the superior mesenteric vein 40% of the time, and portomesenteric confluence at 20% of the time. When there is an obstruction in the portal vein or hepatic veins, portosystemic collateral pathways open to allow the drainage of excessive portal system blood into the systemic venous system.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is true about valves in the portal venous system?", "options": [{"label": "A", "text": "Present at the junction of the superior mesenteric artery with the splenic artery", "correct": false}, {"label": "B", "text": "Within the portal vein only", "correct": false}, {"label": "C", "text": "The whole system is valveless", "correct": true}, {"label": "D", "text": "In the intrahepatic portion of portal vein", "correct": false}], "correct_answer": "C. The whole system is valveless", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The whole system is valveless Valves of the Portal venous system, although demonstrable during the fetal and early neonatal period, there are no valves in the portal vein and its tributaries in the postnatal period.</p>\n<p><strong>Highyeild:</strong></p><p>As the Portal vein courses to the right towards the liver it inclines superiorly, running in the free edge of the lesser omentum (hepatoduodenal ligament) with the other structures of the portal triad (common hepatic duct and common hepatic artery) anterior to it. The portal vein is separated from the inferior vena cava by the epiploic foramen (of Winslow) .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Present at the junction of the superior mesenteric artery with the splenic artery Valves of Portal venous system, although demonstrable during the fetal and early neonatal period, there are no valves in the portal vein and its tributaries in the postnatal period. Option B. Within the portal vein only Valves of the Portal venous system, although demonstrable during the fetal and early neonatal period, there are no valves in the portal vein and its tributaries in the postnatal period. Option D. In the intrahepatic portion of the portal vein Valves of the Portal venous system, although demonstrable during the fetal and early neonatal period, there are no valves in the portal vein and its tributaries in the postnatal period.</p>\n<p><strong>Extraedge:</strong></p><p>The hepatic portal vein is formed from the convergence of the superior mesenteric and splenic veins posterior to the neck of the pancreas at the level of the first lumbar intervertebral disc (in the transpyloric plane) .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Major Porto- caval shunting is seen in which of the following?", "options": [{"label": "A", "text": "Umbilicus", "correct": false}, {"label": "B", "text": "Oesophagus", "correct": false}, {"label": "C", "text": "Rectum and anal canal", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above</p>\n<p><strong>Highyeild:</strong></p><p>Major sites of Portocaval anastomosis</p>\n<p><strong>Extraedge:</strong></p><p>The embryonic vitelline veins drain from the yolk sac to the sinus venosus. The two vitelline veins develop anastomosing cross-communications around the duodenum, the developing liver, and the septum transversum. Selective involution of these veins leads to the formation of the portal vein,, and rotation of the foregut contributes to the formation of its extra-hepatic course. Abnormal involution can lead to congenital abnormalities, including a congenital portosystemic shunt.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 21 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Fascia over the posterior triangle is pierced by:", "options": [{"label": "A", "text": "Spinal Accessory Nerve", "correct": false}, {"label": "B", "text": "hypoglossal nerve", "correct": false}, {"label": "C", "text": "External jugular vein", "correct": true}, {"label": "D", "text": "Internal jugular vein", "correct": false}], "correct_answer": "C. External jugular vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>External jugular vein The roof of the posterior triangle is formed by the investing layer of deep cervical fascia which contains an External jugular vein.</p>\n<p><strong>Highyeild:</strong></p><p>The superficial fascia over the posterior triangle contains: The platysma The external jugular veins Parts of the supraclavicular, great auricular, transverse cutaneous, and lesser occipital nerves Arterial branches are derived from the occipital, transverse cervical, and suprascapular arteries. Lymph vessels that pierce the deep fascia end in the supraclavicular nodes.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Spinal Accessory Nerve The spinal accessory nerve in the posterior triangle passes through the posterior border of the sternocleidomastoid muscle below the tip of the mastoid process and reaches the anterior border of the trapezius above the clavicle. Option:B. Hypoglossal nerve The hypoglossal nerve, or cranial nerve XII, descends posterior to the internal carotid artery and first appears in the carotid triangle as it crosses the lateral surface of the internal and external carotid arteries. Option:D. Internal jugular vein The internal jugular vein lies on the lateral side of the common and internal carotid arteries in the carotid triangle.</p>\n<p><strong>Extraedge:</strong></p><p>The cervical plexus is a plexus of the anterior rami of the first four cervical spinal nerves which arise from the C1 to C4 cervical segment in the neck. They are located laterally to the transverse processes between prevertebral muscles from the medial side and vertebral (m. scalenus, m. levator scapulae, m.splenius cervicis) from the lateral side. It is located in the neck, deep to the sternocleidomastoid muscle. Nerves formed from the cervical plexus innervate the back of the head, as well as some neck muscles. The branches of the cervical plexus emerge from the posterior triangle at the nerve point, a point that lies midway on the posterior border of the sternocleidomastoid.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient has been severely injured in the back of the head during a mugging attempt and imaging studies reveal a possible fracture of the skull along with the C1 (atlas) vertebra. The patient is also hemorrhaging from the vertebral artery in this location, and the attending surgeon will attempt to stop the bleeding by accessing through the suboccipital triangle. Which of the following muscles attaches from the transverse process of C1 to the occipital bone that forms the lateral border of the suboccipital triangle?", "options": [{"label": "A", "text": "Obliquus Capitis Inferior", "correct": false}, {"label": "B", "text": "Obliquus capitis superior", "correct": true}, {"label": "C", "text": "Rectus capitis posterior major", "correct": false}, {"label": "D", "text": "Rectus capitis posterior minor", "correct": false}], "correct_answer": "B. Obliquus capitis superior", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Obliquus capitis superior The obliquus capitis superior, is attached between the transverse process of C1 and the suboccipital bone between the nuchal lines. It forms the lateral border of the suboccipital triangle.</p>\n<p><strong>Highyeild:</strong></p><p>Suboccipital triangle boundaries The rectus capitis posterior major muscle forms the medial border of the triangle. The obliquus capitis superior muscle forms the lateral border. The obliquus capitis inferior muscle forms the inferior border. The contents of the area outlined by these muscles are the posterior ramus of C1, the vertebral artery, and associated veins.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A. The obliquus capitis inferior is the inferior border of the triangle, attaching from the spinous process of C2 to the transverse process of C1. Option: C. The rectus capitis posterior major inserts from the spinous process of C2 into the inferior nuchal line on the occipital bone; it forms the medial border of the suboccipital triangle. Option: D. The rectus capitis posterior minor lies medial to the rectus capitis posterior major. The semispinalis cervicis does not participate in the formation of the suboccipital triangle</p>\n<p><strong>Extraedge:</strong></p><p>Weakness in the trapezius, caused by an interruption of the accessory nerve [XI], may appear as drooping of the shoulder, inability to raise the arm above the head because of impaired rotation of the scapula, or weakness in attempting to raise the shoulder (i.e., shrug the shoulder against resistance).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Contents of the posterior triangle of the neck are:", "options": [{"label": "A", "text": "Occipital artery, spinal accessory nerve, hypoglossal, ascending pharyngeal artery", "correct": false}, {"label": "B", "text": "Occipital artery, lesser occipital nerve, subclavian artery, spinal accessory nerve", "correct": true}, {"label": "C", "text": "Occipital artery, spinal accessory nerve, subclavian artery, hypoglossal nerve", "correct": false}, {"label": "D", "text": "Occipital artery, Lesser occipital nerve, ascending pharyngeal artery, vagus nerve", "correct": false}], "correct_answer": "B. Occipital artery, lesser occipital nerve, subclavian artery, spinal accessory nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Occipital artery, lesser occipital nerve, subclavian artery, spinal accessory nerve Option:A. Occipital artery, spinal accessory nerve, hypoglossal nerve, ascending pharyngeal artery The hypoglossal nerve and ascending pharyngeal artery are the content of the anterior triangle. Option:C. Occipital artery, spinal accessory nerve, subclavian artery, hypoglossal nerve The hypoglossal nerve is the content of the anterior triangle. Option:D. Occipital artery, Lesser occipital nerve, ascending pharyngeal artery, vagus nerve. The vagus nerve and ascending pharyngeal artery are the content of the anterior triangle.</p>\n<p><strong>Extraedge:</strong></p><p>The roof is formed by the investing layer of deep cervical fascia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The floor of the posterior triangle of the neck is formed by:", "options": [{"label": "A", "text": "Semispinalis capitis, levator scapulae, scalenus anterior, scalenus medius", "correct": false}, {"label": "B", "text": "Levator scapulae, splenius capitis, scalenus medius, semispinalis capitis", "correct": true}, {"label": "C", "text": "Semispinalis capitis, scalenus anterior, splenius capitis, sternocleidomastoid", "correct": false}, {"label": "D", "text": "Levator scapulae, scalenus posterior, semispinalis capitis, scalenus medius", "correct": false}], "correct_answer": "B. Levator scapulae, splenius capitis, scalenus medius, semispinalis capitis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Levator scapulae, splenius capitis, scalenus medius, semispinalis capitis The floor of the posterior triangle is formed by the prevertebral layer of deep cervical fascia, covering the following muscles: Splenius capitis. Levator scapulae. Scalenus medius Semispinalis capitis may also form part of the floor. The floor of Posterior triangle</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Semispinalis capitis, levator scapulae, scalenus anterior, scalenus medius Option:C. Semispinalis capitis, scalenus anterior, splenius capitis, sternocleidomastoid Option:D. Levator scapulae, scalenus posterior, semispinalis capitis, scalenus medius Options A, C, and D are incorrect answers because: The floor of the posterior triangle is muscular and is formed from above downwards by the following muscles : Semispinalis capitis. Splenius capitis. Levator scapulae. Scalenus medius. First digitation of serratus anterior (sometimes)</p>\n<p><strong>Extraedge:</strong></p><p>Division of the Posterior Triangle It is subdivided by the inferior belly of omohyoid into:1. A larger upper part, called the occipital part. 2. A smaller lower part, called the supraclavicular part or subclavian part</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following structures is not seen in the posterior triangle of the neck:", "options": [{"label": "A", "text": "Spinal Accessory Nerve", "correct": false}, {"label": "B", "text": "Transverse cervical artery", "correct": false}, {"label": "C", "text": "Middle trunk of brachial plexus", "correct": false}, {"label": "D", "text": "Superior belly of omohyoid", "correct": true}], "correct_answer": "D. Superior belly of omohyoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior belly of omohyoid The anterior triangle is subdivided (by the digastric muscle and the superior belly of the omohyoid) into: a. Submental, b. Digastric, c. Carotid, and d. Muscular triangles</p>\n<p><strong>Highyeild:</strong></p><p>Division of the Posterior Triangle It is subdivided by the inferior belly of omohyoid into: 1. A larger upper part, called the occipital triangle. 2. A smaller lower part, called the supraclavicular or the subclavian triangle. Content of the Posterior Triangle Contents Occipital triangle Subclavian triangle A. Nerves. 1. Spinal accessory nerve2. Four cutaneous branches of cervical plexus: a. Lesser occipital (C2) b. Great auricular (C2, C3) c. Anterior cutaneous nerve of neck (C2, C3) d. Supraclavicular nerves (C3, C4)3. Muscular branches: a. Two small branches to the levator scapulae (C3, C4) b. Two small branches to the trapezius (C3, C4) c. Nerve to rhomboids (proprioceptive) (C5)4. C5, C6 roots of the brachial plexus 1. Three trunks of brachial plexus2. Nerve to serratus anterior (long thoracic, C5,C6, C7)3. Nerve to subclavius (C5, C6)4. Suprascapular nerve (C5, C6) B. Vessels 1. Transverse cervical artery and vein2. Occipital artery 1. Third part of subclavian artery and subclavianvein2. Suprascapular artery and vein3. Commencement of transverse cervical artery and termination of the corresponding vein4. Lower part of external jugular veinC. Lymph nodes C. Lymph nodes Along the posterior border of the sternocleidomastoid, more in the lower part-the supraclavicular nodes and a few at the upper angle-the occipital nodes A few members of the supraclavicular chain</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Spinal Accessory Nerve Option:B. Transverse cervical artery Option:C. Middle trunk of brachial plexus Options A, B, and C all are content of the posterior triangle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following muscles is supplied by the Spinal root of the accessory nerve?", "options": [{"label": "A", "text": "Serratus Anterior", "correct": false}, {"label": "B", "text": "Stylohyoid", "correct": false}, {"label": "C", "text": "Styloglossus", "correct": false}, {"label": "D", "text": "Sternocleidomastoid", "correct": true}], "correct_answer": "D. Sternocleidomastoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sternocleidomastoid The spinal accessory nerve emerges a little above the middle of the posterior border of the sternocleidomastoid. It runs through a tunnel in the fascia forming the roof of the triangle, passing downwards and laterally, and disappears under the anterior border of the trapezius about 5 cm above the clavicle. It is the only structure beneath the roof of the triangle. Sternocleidomastoid muscle innervated by Spinal accessory nerve</p>\n<p><strong>Highyeild:</strong></p><p>Nerve Supply of sternocleidomastoid muscle The spinal accessory nerve provides the motor supply. It passes through the muscle. Branches from the ventral rami of C2 and C3 are proprioceptive.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A: Serratus Anterior is supplied by the Long thoracic nerve and a branch of the intercostal nerve. Option B: Stylohyoid muscle is supplied by the stylohyoid branch of the facial nerve Option C: Styloglossus is supplied by the hypoglossal nerve</p>\n<p><strong>Extraedge:</strong></p><p>Blood Supply of sternocleidomastoid muscle Arterial supply—one branch each from the superior thyroid artery and suprascapular artery and two branches from the occipital artery supply the big muscle. Veins follow the arteries.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Investing layer of the cervical fascia encloses all except:", "options": [{"label": "A", "text": "Two Muscles", "correct": false}, {"label": "B", "text": "Two salivary glands", "correct": false}, {"label": "C", "text": "Axillary vessels", "correct": true}, {"label": "D", "text": "Two spaces", "correct": false}], "correct_answer": "C. Axillary vessels", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Axillary vessels The axillary sheath is a fibrous sheath that encloses the axillary artery and the three cords of the brachial plexus to form the neurovascular bundle. It is surrounded by axillary fat. It is an extension of the prevertebral fascia of the deep cervical fascia and is continuous with the carotid sheath at the venous angle.</p>\n<p><strong>Highyeild:</strong></p><p>INVESTING LAYER It lies deep into the platysma and surrounds the neck like a collar. It forms the roof of the posterior triangle of the neck. The investing layer of deep cervical fascia splits to enclose: Muscles: Trapezius and sternocleidomastoid. Salivary glands: Parotid and submandibular. Spaces: Suprasternal and supraclavicular. 2 It also forms pulleys to bind the tendons of the digastric and omohyoid muscles. 3 Forms roof of anterior and posterior triangles. 4 Forms stylomandibular ligament and parotido-masseteric fascia. Transverse section through the neck at the level of the 6th cervical vertebra to show the horizontal disposition of the three layers of deep cervical fascia.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- The investing layer of deep cervical fascia splits to enclose: Option A: Muscles: Trapezius and sternocleidomastoid. Option B: Salivary glands: Parotid and submandibular. Option D: Spaces: Suprasternal and supraclavicular.</p>\n<p><strong>Extraedge:</strong></p><p>The suprasternal space contains: (a) sternal head of sternocleidomastoid muscles,(b) jugular venous arch, (c) interclavicular ligament,and (d) lymph nodes (sometimes).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following fascia forms the Ligament of Berry?", "options": [{"label": "A", "text": "Investing layer of cervical fascia", "correct": false}, {"label": "B", "text": "Pretracheal layer", "correct": true}, {"label": "C", "text": "Prevertebral layer", "correct": false}, {"label": "D", "text": "Buccopharyngeal fascia", "correct": false}], "correct_answer": "B. Pretracheal layer", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Pretracheal layer PRETRACHEAL FASCIA On either side, the pretracheal fascia forms a suspensory ligament for the thyroid gland known as the ligament of Berry . The ligaments are attached chiefly to the cricoid cartilage and may extend to the thyroid cartilage. They support the thyroid gland and do not let it sink into the mediastinum. The importance of this fascia is that it encloses and suspends the thyroid gland and forms its false capsule.</p>\n<p><strong>Highyeild:</strong></p><p>Occipital triangle content A. Nerves Option A: Spinal accessory nerve Four cutaneous branches of the cervical plexus: Option B: Lesser occipital (C2) Great auricular (C2, C3) Anterior cutaneous nerve of the neck (C2, C3) Supraclavicular nerves (C3, C4) Muscular branches: Two small branches to the levator scapulae (C3, C4) Two small branches to the trapezius (C3, C4) Nerve to rhomboids (proprioceptive) (C5) C5, and C6 roots of the brachial plexus B. Vessels Option C: Transverse cervical artery and vein Occipital artery C. Lymph nodes Along the posterior border of the sternocleidomastoid more in the lower part-the supraclavicular nodes and a few at the upper angle-the occipital nodes. Therefore all of the above option D is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A: The investing layer of the cervical fascia of the neck is a tough layer of fibrous tissue arranged like a collar around the neck. It is attached below to the upper surface of the clavicle. It splits to enclose the sternocleidomastoid and trapezius muscles on each side. Option C: The prevertebral fascia (or prevertebral layer of cervical fascia) is a fascia in the neck. The prevertebral fascia extends medially behind the carotid vessels, where it assists in forming their sheath and passes in front of the prevertebral muscles. Option D: Buccopharyngeal Fascia envelops the superior pharyngeal constrictor muscles. It closely invests the constrictor muscles of the pharynx. It is continued forward from the constrictor pharynx superior onto the buccinator.</p>\n<p><strong>Extraedge:</strong></p><p>PRETRACHEAL FASCIA The posterior layer of the thyroid capsule is thick. On either side, it forms a suspensory ligament for the thyroid gland known as the ligament of Berry. The ligaments are attached chiefly to the cricoid cartilage and may extend to the thyroid cartilage. They support the thyroid gland and do not let it sink into the mediastinum. The capsule of the thyroid is very weak along the posterior borders of the lateral lobes. The fascia provides a slippery surface for free movements of the trachea during swallowing</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The floor of the occipital triangle is formed by all the following except Levator scapulae Splenius capitis Scalenus posterior Scalenus anterior Scalenus medius Select the correct answer given below code:", "options": [{"label": "A", "text": "If option A and B are correct", "correct": false}, {"label": "B", "text": "If option C and D are correct", "correct": true}, {"label": "C", "text": "If option A and D are correct", "correct": false}, {"label": "D", "text": "If all the options are correct", "correct": false}], "correct_answer": "B. If option C and D are correct", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>If option C and D are correct The floor of the posterior triangle is muscular and is formed from above downwards by the following muscles : Semispinalis capitis. Splenius capitis. Levator scapulae. Scalenus medius. First digitation of serratus anterior (sometimes)</p>\n<p><strong>Highyeild:</strong></p><p>The most important contents of the posterior triangle are: (a) the third part of the subclavian artery, (b) brachial plexus (cervical part), (c) spinal accessory nerve, and (d) lymph nodes.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- The floor of the posterior triangle is formed by the prevertebral layer of deep cervical fascia, covering the following muscles: Splenius capitis. 2. Levator scapulae. 3. Scalenus medius 4. Semispinalis capitis may also form part of the floor. The floor of the posterior triangle</p>\n<p><strong>Extraedge:</strong></p><p>All the important contents of the posterior triangle lie deep into the fascial carpet of the floor except spinal accessory nerve, which lies just underneath the roof. In operations on the posterior triangle all the structures except the spinal accessory nerves are safe, provided the fascial carpet of the posterior triangle is left intact.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not a content of the pointed triangle:", "options": [{"label": "A", "text": "Suprascapular Nerve", "correct": false}, {"label": "B", "text": "Superficial cervical artery", "correct": false}, {"label": "C", "text": "Long thoracic nerve", "correct": false}, {"label": "D", "text": "Thoracodorsal nerve", "correct": true}], "correct_answer": "D. Thoracodorsal nerve", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681520646-QTDA031010IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thoracodorsal nerve Content of the subclavian/supraclavicular triangle (i.e., below the omohyoid) 3rd part of the subclavian artery Subclavian vein The terminal part of the external jugular vein Trunks of brachial plexus Superficial (transverse) cervical, suprascapular, and dorsal scapular arteries Lymph nodes.</p>\n<p><strong>Highyeild:</strong></p><p>Subclavian triangle contents Nerves Three trunks of brachial plexus Nerve to serratus anterior (long thoracic, C5, C6, C7) Nerve to subclavius (C5, C6) Suprascapular nerve (C5, C6) Vessels The third part of the subclavian artery and subclavian vein Suprascapular artery and vein Commencement of transverse cervical artery and termination of the corresponding vein The lower part of the external jugular vein Lymph nodes A few members of the supraclavicular chain;</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Suprascapular Nerve Superficial cervical artery Long thoracic nerve The suprascapular Nerve, Superficial cervical artery, and Long thoracic nerve all are content of the subclavian triangle.</p>\n<p><strong>Extraedge:</strong></p><p>Three trunks of the brachial plexus emerge between the scalenus anterior and medius and carry the axillary sheath around them. The sheath contains the brachial plexus and the subclavian artery. These structures lie deep to the floor of the posterior triangle. If the prevertebral fascia is left intact, all these structures are safe</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A superficial incision to open a subcutaneous abscess at the middle of the posterior border of the sternocleidomastoid might damage.", "options": [{"label": "A", "text": "Lesser Occipital Nerve", "correct": false}, {"label": "B", "text": "Transverse cervical cutaneous nerve", "correct": false}, {"label": "C", "text": "Spinal accessory nerve", "correct": true}, {"label": "D", "text": "Supraclavicular nerve", "correct": false}], "correct_answer": "C. Spinal accessory nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spinal accessory nerve The spinal accessory nerve may be damaged in operations involving the removal or biopsy of lymph nodes in the posterior triangle of the neck.</p>\n<p><strong>Highyeild:</strong></p><p>The spinal accessory nerve emerges a little above the middle of the posterior border of the sternocleidomastoid. It runs through a tunnel in the fascia forming the roof of the triangle, passing downwards and laterally, and disappears under the anterior border of the trapezius about 5 cm above the clavicle. It is the only structure beneath the roof of triangle. In the posterior triangle, it is adherent to the deep aspect of the fascial roof of this triangle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options: A, B, and D are incorrect answers because the spinal accessory nerve is the only structure beneath the roof of the triangle. It supplies both sternocleidomastoid and trapezius muscles.</p>\n<p><strong>Extraedge:</strong></p><p>More proximally, the Spinal accessory nerve lies in front of the transverse process of the atlas vertebra runs downwards and laterally to enter the anterior border of the sternocleidomastoid muscle between its upper two quarters and supplies it.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following are the contents of the occipital triangle?", "options": [{"label": "A", "text": "Spinal Accessory Nerve", "correct": false}, {"label": "B", "text": "Lesser occipital nerve", "correct": false}, {"label": "C", "text": "Transverse cervical artery", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above Occipital triangle content A. Nerves Option A: Spinal accessory nerve Four cutaneous branches of the cervical plexus: Option B: Lesser occipital (C2) Great auricular (C2, C3) Anterior cutaneous nerve of the neck (C2, C3) Supraclavicular nerves (C3, C4) Muscular branches: Two small branches to the levator scapulae (C3, C4) Two small branches to the trapezius (C3, C4) Nerve to rhomboids (proprioceptive) (C5) C5, and C6 roots of the brachial plexus B. Vessels Option C: Transverse cervical artery and vein Occipital artery C. Lymph nodes Along the posterior border of the sternocleidomastoid more in the lower part-the supraclavicular nodes and a few at the upper angle-the occipital nodes. Therefore all of the above option D is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>A cervical rib may compress the second part of the subclavian artery. In these cases, the blood supply to the upper limb reaches via anastomoses around the scapula Block Dissection Of the neck for Malignant Diseases is the removal of cervical lymph nodes along with other structures involved in the growth. This procedure does not endanger those nerves of the posterior triangle which lie deep into the prevertebral fascia, i.e. the brachial and cervical plexuses and their muscular branches.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 22 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The following muscles are supplied by radial nerve below the spiral groove, except:", "options": [{"label": "A", "text": "Extensor Carpi Radialis Brevis", "correct": false}, {"label": "B", "text": "Brachioradialis", "correct": false}, {"label": "C", "text": "Extensor Carpi Radialis Longus", "correct": false}, {"label": "D", "text": "Anconeus", "correct": true}], "correct_answer": "D. Anconeus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anconeus The radial nerve gives a branch to the anconeus muscle in the groove, not below it.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Extensor carpi radialis brevis Extensor carpi radialis brevis is innervated by radial nerves below the spiral groove. Option: B. Brachioradialis Brachioradialis is innervated by radial nerves below the spiral groove. Option: C. Extensor carpi radialis longus Extensor carpi radialis longus is innervated by radial nerves below the spiral groove. Radial nerve Branches</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The radial nerve passes through the radial groove, which is the other one.", "options": [{"label": "A", "text": "Ulnar Nerve", "correct": false}, {"label": "B", "text": "Median Nerve", "correct": false}, {"label": "C", "text": "Musculocutaneous Nerve", "correct": false}, {"label": "D", "text": "Lower lateral cutaneous nerve of arm", "correct": true}], "correct_answer": "D. Lower lateral cutaneous nerve of arm", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lower lateral cutaneous nerve of arm In the radial groove , the radial nerve gives off the lower lateral cutaneous nerves of the arm and the posterior cutaneous nerve of the forearm. So, these two nerves along with the radial nerve and profunda brachii artery , pass through the radial groove.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A, B & C. The ulnar nerve, Median nerve and Musculocutaneous nerves do not traverse through the radial groove .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Division of radial nerve occurs at which bony landmark?", "options": [{"label": "A", "text": "Anterior part of medial epicondyle", "correct": false}, {"label": "B", "text": "Anterior part of lateral epicondyle", "correct": true}, {"label": "C", "text": "Posterior part of medial epicondyle", "correct": false}, {"label": "D", "text": "Posterior part of lateral epicondyle", "correct": false}], "correct_answer": "B. Anterior part of lateral epicondyle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior part of lateral epicondyle The radial nerve passes in front of the lateral condyle of the humerus & divides into two terminal branches.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - The radial nerve is not divided into its terminal branches at the above level, so options A, C and D are incorrect.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Cutaneous innervation of marked area is given by:", "options": [{"label": "A", "text": "Radial Nerve", "correct": true}, {"label": "B", "text": "Posterior Interosseous Nerve", "correct": false}, {"label": "C", "text": "Median Nerve", "correct": false}, {"label": "D", "text": "Ulnar Nerve", "correct": false}], "correct_answer": "A. Radial Nerve", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683840480-QTDA105004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Radial Nerve The radial nerve provides sensory innervation for the dorsal aspect of the radial (i.e. lateral) three-and-a-half digits of the hand ( e. thumb, index, middle, and lateral half of ring finger) but not the nail buds. Within the arms and forearm, sensory branches are given off that provide innervation for the skin on the posterior and outer surfaces of the arm and forearm.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Posterior interosseous nerve The posterior interosseous nerve is a deep motor branch of the radial nerve. It innervates all the extensor muscles of the forearm except the Brachioradialis and Extensor carpi radialis longus. Option: C. Median nerve The median nerve provides sensory innervation to the hand. This includes the palmar and distal dorsal aspects of the lateral three-and-a-half digits (thumb, index, middle, and half of the ring finger) and central palm The sensation of the palm is provided by the median nerve and a small sensory branch known as the palmar cutaneous, which branches before the carpal tunnel. Option: D. Ulnar nerve The ulnar nerve provides a sensory function to the skin of both the palmar and dorsal aspects of the medial one-and-a-half digits and adjacent palm. In other words, the little finger and medial side of the ring finger. It also provides sensation to the medial side of the dorsum of the hand. Cutaneous Innervation of Hand</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The patient is brought to the emergency room with a history of trauma to the right upper limb. Extension of metacarpo-phalangeal joint is lost. There is no wrist drop, and the extension of the IP joint is normal. The most likely nerve involved is:", "options": [{"label": "A", "text": "Ulnar Nerve", "correct": false}, {"label": "B", "text": "Median Nerve", "correct": false}, {"label": "C", "text": "Radial Nerve", "correct": false}, {"label": "D", "text": "Posterior Interosseous Nerve", "correct": true}], "correct_answer": "D. Posterior Interosseous Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior Interosseous Nerve Wrist drop is not seen in PIN injury because Brachioradialis and Extensor Carpi radialis longus are still intact due to their direct innervation via a radial nerve. ECRL is still able to perform wrist extension. Extension of IP joints is done by lumbricals, which are supplied by the Ulnar and median nerve, so they are also normal in the above case. The posterior interosseous nerve causes the extension of metacarpo-phalangeal joint, which is lost in the given case scenario, hence the answer is option D.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Ulnar Nerve The ulnar nerve is not responsible for the extension of metacarpophalangeal joints. Option: B. Median nerve The median nerve is not responsible for the extension of metacarpophalangeal joints. Option: C. Radial nerve If a radial nerve is injured the patient will present with a wrist drop, so it is an incorrect option.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A bookshelf falls on a person's arm laterally. He presents with an inability to extend his wrist. On examination, he is unable to make a strong hand grip and there is a loss of sensation on the dorsum of the hand and fingers. Which of the following nerves is injured?", "options": [{"label": "A", "text": "Brachial Plexus", "correct": false}, {"label": "B", "text": "Radial Nerve Injury", "correct": true}, {"label": "C", "text": "Posterior Cord Injury", "correct": false}, {"label": "D", "text": "Ulnar Nerve Injury", "correct": false}], "correct_answer": "B. Radial Nerve Injury", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Radial Nerve Injury Loss Of wrist extension and loss of sensation along the dorsum of the hand and fingers suggest radial nerve injury. Wrist Drop</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Brachial Plexus - Brachial plexus injury presents with waiter tip deformity or Klumpke palsy. Option: C. Posterior cord injury - Posterior cord injury will result in the involvement of all its branches. Radial nerve Axillary nerve Upper subscapular nerve Lower Subscapular nerve Thoracodorsal nerve. Option D. Ulnar nerve injury- Ulnar nerve injury will present with the medial claw hand.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Root value of sciatic nerve?", "options": [{"label": "A", "text": "L4-S3", "correct": true}, {"label": "B", "text": "L5-S2", "correct": false}, {"label": "C", "text": "L4-S1", "correct": false}, {"label": "D", "text": "S2-S3", "correct": false}], "correct_answer": "A. L4-S3", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>L4-S3 The sciatic nerve is the largest branch of the sacral plexus and runs alongside the hip joint and down the lower limb. It is the longest and widest single nerve in the human body, going from the top of the leg to the foot on the posterior aspect. I t is derived from spinal nerves L4 to S3. It contains fibres from both the anterior and posterior divisions of the lumbosacral plexus.</p>\n<p><strong>Highyeild:</strong></p><p>The sciatic nerve has no cutaneous branches for the thigh . This nerve provides the connection to the nervous system for the skin of the lateral leg and the whole foot, the muscles of the back of the thigh, and those of the leg and foot.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B - Nerve to obturator internus and gemellus superior-L5-S2 Option C - Nerve to quadratus femoris and gemellus inferior L4-S1 Option D - Posterior femoral cutaneous S2-S3</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following structures pass below piriformis?", "options": [{"label": "A", "text": "Sciatic Nerve", "correct": true}, {"label": "B", "text": "Superior gluteal artery", "correct": false}, {"label": "C", "text": "Superior gluteal vein", "correct": false}, {"label": "D", "text": "Inferior gluteal artery", "correct": false}], "correct_answer": "A. Sciatic Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sciatic Nerve The sciatic nerve leaves the pelvis via the greater sciatic foramen below piriformis and descends between the greater trochanter and ischial tuberosity, along the back of the thigh. Sciatic nerve passing below piriformis muscle</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B- The superior gluteal artery is the largest branch of the internal iliac artery and, effectively, forms the main continuation of its posterior trunk. It runs posteriorly between the lumbosacral trunk and the first sacral ramus or between the first and second rami. Then it turns slightly inferiorly, leaving the pelvis by the greater sciatic foramen above piriformis and dividing into superficial and deep branches. Option C- The superior gluteal veins are the venae comitantes of the superior gluteal artery. They receive tributaries corresponding to the superior gluteal artery branches and enter the pelvis via the greater sciatic foramen, above piriformis. They join the internal iliac vein, frequently as a single trunk. Option D- The inferior gluteal artery is the larger terminal branch of the anterior internal iliac trunk and principally supplies the buttock and thigh. It descends posteriorly, anterior to the sacral plexus and piriformis, but posterior to the internal pudendal artery. It passes between the first, second, or second and third sacral ventral rami, then between piriformis and ischiococcygeus, before running through the lower part of the greater sciatic foramen to reach the gluteal region.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following structures pass through the greater sciatic foramen?", "options": [{"label": "A", "text": "Internal Pudendal Artery", "correct": false}, {"label": "B", "text": "Internal pudendal vein", "correct": false}, {"label": "C", "text": "Sciatic nerve", "correct": true}, {"label": "D", "text": "Obturator nerve", "correct": false}], "correct_answer": "C. Sciatic nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sciatic nerve The sciatic nerve is 2 cm wide at its origin and is the thickest nerve in the body The sciatic nerve leaves the pelvis via the greater sciatic foramen below the piriformis and descends between the greater trochanter and ischial tuberosity along the back of the thigh, dividing into the tibial and common fibular nerves at a varying level proximal to the knee.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - The internal pudendal artery is the smaller terminal branch of the anterior division of the internal iliac artery. Close to its origin, it crosses anterior to the piriformis, the sacral plexus and the inferior gluteal artery. It descends laterally to the inferior rim of the greater sciatic foramen, where it leaves the pelvis between the piriformis and is chi coccygeus and enters the gluteal region. It next curves around the dorsum of the ischial spine and enters the ischiorectal fossa via the lesser sciatic foramen. Option B - The internal pudendal veins are venae comitantes of the internal pudendal artery and unite as a single vessel that drains into the internal iliac vein. They receive veins from the inferior rectal veins, the penile bulb and scrotum (males), or the clitoris and labia (females). Option D - Obturator nerve - The obturator nerve arises from the ventral branches of the second to fourth lumbar ventral rami. The branch from the third is the largest, while that from the second is often very small. The nerve descends in the psoas major, emerging from its medial border at the pelvic brim to pass behind the common iliac vessels and lateral to the internal iliac vessels. It then descends forwards along the lateral wall of the lesser pelvis on the obturator internus, anterosuperior to the obturator vessels, to the obturator foramen, entering the thigh by its upper part. Near the foramen, it divides into anterior and posterior branches, separated at first by part of obturator externus and lower down by adductor brevis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following is supplied by the common fibular division of the sciatic nerve?", "options": [{"label": "A", "text": "The long head of the biceps femoris", "correct": false}, {"label": "B", "text": "The short head of the biceps femoris", "correct": true}, {"label": "C", "text": "Semitendinosus", "correct": false}, {"label": "D", "text": "Semimembranosus", "correct": false}], "correct_answer": "B. The short head of the biceps femoris", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The short head of the biceps femoris Biceps femoris is innervated by the sciatic nerve, the long head through the tibial division and the short head through the common fibular division, a distribution that reflects the composite derivation from flexor and extensor musculature. Sciatic nerve divisions</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A- Biceps femoris is innervated by the sciatic nerve, L5, S1 and 2: the long head through the tibial division and the short head through the common fibular division, a distribution that reflects the composite derivation from flexor and extensor musculature. Option C- Semitendinosus is innervated by the sciatic nerve, L5, S1 and 2, through its tibial division. Option D- Semimembranosus is innervated by the sciatic nerve, L5, S1 and 2, through its tibial division.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "What is the root value of the common fibular division of the sciatic nerve?", "options": [{"label": "A", "text": "L4-S2", "correct": true}, {"label": "B", "text": "L5-S2", "correct": false}, {"label": "C", "text": "L4-S1", "correct": false}, {"label": "D", "text": "S2-S3", "correct": false}], "correct_answer": "A. L4-S2", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>L4-S2 Common peroneal nerve is the smaller and terminal branch of the sciatic nerve, composed of the posterior divisions of L4, 5, S1, and 2.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B- Nerve to obturator internus and gemellus superior L5-S2 Option C- Nerve to quadratus femoris and gemellus inferior L4-S1 Option D- Posterior femoral cutaneous S2-S3</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Main blood supply of sciatic nerve in the gluteal region:", "options": [{"label": "A", "text": "Perforating branch of profunda femoris artery", "correct": false}, {"label": "B", "text": "Inferior gluteal artery and cruciate anastomosis", "correct": true}, {"label": "C", "text": "Superior gluteal artery", "correct": false}, {"label": "D", "text": "Popliteal artery", "correct": false}], "correct_answer": "B. Inferior gluteal artery and cruciate anastomosis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior gluteal artery and cruciate anastomosis In the gluteal region, the sciatic nerve is supplied by the inferior gluteal artery and cruciate anastomosis (the medial and lateral circumflex femoral arteries, inferior gluteal artery and the first perforating branch of the profunda femoris artery).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - In the thigh, arterial branches are derived from the perforating branches of the profunda femoris artery or the anastomotic chain between them. Option C - On rare occasions, in the gluteal region, it is supplied by branches from the superior gluteal or internal pudendal arteries, which reach the nerve on its medial side. Option D - Lower in the thigh, arterial branches derived from the perforating branches of the profunda femoris artery or the anastomotic chain between them or, occasionally, from the popliteal artery enter the nerve on its lateral or anterolateral side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Piriformis syndrome is due to which nerve?", "options": [{"label": "A", "text": "Sciatic Nerve", "correct": true}, {"label": "B", "text": "Tibial nerve", "correct": false}, {"label": "C", "text": "Common fibular nerve", "correct": false}, {"label": "D", "text": "Superficial fibular nerve", "correct": false}], "correct_answer": "A. Sciatic Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sciatic Nerve Piriformis syndrome is a controversial condition in which an anomalous relationship between the piriformis and the sciatic nerve is thought to cause pain in the buttocks and along the course of the sciatic nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B - The tibial nerve or the medial and lateral plantar nerves may become entrapped beneath the flexor retinaculum or the so-called plantar tunnels (beneath the fascia of the abductor hallucis) at the ankle, resulting in tarsal tunnel syndrome. Option C - T he common fibular nerve is relatively unprotected as it traverses the lateral aspect of the neck of the fibula and is easily compressed at this site, e.g. by plaster casts or ganglia. The nerve may also become entrapped by a fascial band beneath the fibularis longus within the so-called fibular tunnel, between the attachments of fibularis longus to the head and shaft of the fibula leading to traction lesion. Option D - Lessions of the superficial fibular nerve-A lesion of the superficial fibular nerve causes weakness of foot eversion and sensory loss on the lateral aspect of the leg that extends onto the dorsum of the foot. The nerve can be subject to entrapment as it penetrates the deep fascia of the leg, and it may also be involved in compartment syndrome that affects the lateral compartment of the leg.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which of the following movement is not involved in the abduction of the shoulder?", "options": [{"label": "A", "text": "Medial rotation of scapula", "correct": true}, {"label": "B", "text": "Elevation of humerus", "correct": false}, {"label": "C", "text": "Rotation of clavicle at the sternoclavicular joint", "correct": false}, {"label": "D", "text": "Rotation at the axis of acromioclavicular joint", "correct": false}], "correct_answer": "A. Medial rotation of scapula", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Medial rotation of scapula Lateral (and not medial) rotation of the scapula occurs during abduction of the shoulder. This is done by the serratus anterior and trapezius.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Elevation of the humerus Elevation of the humerus is carried out by the deltoid muscle. This occurs along with the scapular rotation and makes the humerus get lodged in subacromial space. Option: C. Rotation of clavicle at the sternoclavicular joint Abduction at the shoulder involves rotation of the clavicle , This rotation occurs at both the sternoclavicular and the acromioclavicular joints. Option: D. Rotation at the axis of the acromioclavicular joint Abduction at the shoulder involves rotation of the clavicle, This rotation occurs at both the sternoclavicular and the acromioclavicular joints.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following structure is Intracapsular but extra synovial :", "options": [{"label": "A", "text": "Long head of triceps brachii", "correct": false}, {"label": "B", "text": "Long head of biceps brachii", "correct": true}, {"label": "C", "text": "Short head of biceps brachii", "correct": false}, {"label": "D", "text": "Medial head of biceps brachii", "correct": false}], "correct_answer": "B. Long head of biceps brachii", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Long head of biceps brachii The long head of the biceps brachii is intracapsular and intrasynovial, but enclosed by a prolongation of the synovial membrane. Long head of Biceps brachii in relation to the shoulder joint</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Long head of triceps brachii The long head of the Triceps brachii is not an intracapsular and extra synovial structure. Option: C. Short head of biceps brachii The short head of the biceps brachii is not an intracapsular and extra synovial structure. Option: D. Medial head of biceps brachii There is no medial head of the Biceps brachii.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Initiation of abduction at the shoulder joint is affected by injury to which of the following nerve?", "options": [{"label": "A", "text": "Axillary Nerve", "correct": false}, {"label": "B", "text": "Spinal accessory nerve", "correct": false}, {"label": "C", "text": "Long thoracic nerve", "correct": false}, {"label": "D", "text": "Suprascapular nerve", "correct": true}], "correct_answer": "D. Suprascapular nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Suprascapular nerve Initiation of abduction (0 to 15) is done by supraspinatus - innervated by the suprascapular nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Axillary Nerve 15 to 90 abduction is done by the middle fibres of the deltoid muscle - innervated by the axillary nerve Option: B. Spinal accessory nerve 90 to 180 abduction is done by the trapezius and serratus anterior - nerve supply of the trapezius muscle is via the spinal accessory nerve. Option: C. Long thoracic nerve 90 to 180 abduction is done by the trapezius and serratus anterior - the long thoracic nerve is the nerve supply of the serratus anterior muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The knowledge about the biomechanics of the rotator cuff muscles has increased exponentially. The role of one of the rotator cuff muscles had been ignored and less importance had been attached to its role; it is also known as the 'forgotten muscle’. Which of the following is that muscle?", "options": [{"label": "A", "text": "Supraspinatus", "correct": false}, {"label": "B", "text": "Infraspinatus", "correct": false}, {"label": "C", "text": "Teres minor", "correct": false}, {"label": "D", "text": "Subscapularis", "correct": true}], "correct_answer": "D. Subscapularis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Subscapularis The forgotten muscle of the rotator cuff group is subscapularis because of its deep location.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A, B and C are not regarded as forgotten in respect to rotator cuff muscle. Rotator Cuff muscles in respect to Shoulder joint</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not an example of epiphysis?", "options": [{"label": "A", "text": "Lesser Trochanter", "correct": false}, {"label": "B", "text": "Greater Tubercle", "correct": false}, {"label": "C", "text": "Deltoid Tuberosity", "correct": true}, {"label": "D", "text": "Coracoid Process", "correct": false}], "correct_answer": "C. Deltoid Tuberosity", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Deltoid Tuberosity Deltoid tuberosity is a rough, triangular area on the anterolateral (front-side) surface of the middle of the humerus . It is a site of attachment of the deltoid muscle. It is not epiphysis, but diaphysis part of the humerus bone.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Lesser Trochanter Traction epiphysis: Non-articular and does not take part in weight transmission. Greater and lesser trochanter of the femur and Greater and lesser tubercle of the humerus bone are examples of traction epiphysis. Option: B. Greater tubercle Traction epiphysis: Non-articular and does not take part in weight transmission. Greater and lesser trochanter of the femur and Greater and lesser tubercle of the humerus bone. Option: D. Coracoid process Atavistic epiphysis: Phylogenetically independent but fused to the nearest bone for nutrition. The coracoid process of the scapula and Os trigonum are examples of the atavistic epiphysis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were posted in ortho OPD where a junior resident was examining the shoulder joint of the patient. He asks you about the variety of joints. Which other joint is also having the same variety of joints?", "options": [{"label": "A", "text": "Incudo-Stapedial Joint", "correct": false}, {"label": "B", "text": "Talo-calcaneo-navicular joint", "correct": false}, {"label": "C", "text": "Elbow joint", "correct": false}, {"label": "D", "text": "Both A and B.", "correct": true}], "correct_answer": "D. Both A and B.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Both A and B. Option: A. Incudo-Stapedial Joint Option: B. Talo-calcaneo-navicular joint In the given question, the shoulder joint is examined by the JR. It is an example of a ball and socket type of synovial joint. The other joint which is ball and socket-type joint are: Incudo-stapedial joint Talo-calcaneo-navicular joint. Hence, the answer is option D. Option: C. Elbow joint The elbow joint is an example of a hinge variety of synovial joints.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During your radiological posting, the following X-ray image was shown. Which of the following structures are involved in the shoulder joint?", "options": [{"label": "A", "text": "1,2", "correct": false}, {"label": "B", "text": "2,4", "correct": false}, {"label": "C", "text": "1,3", "correct": true}, {"label": "D", "text": "2,3", "correct": false}], "correct_answer": "C. 1,3", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683867079-QTDA106007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,3 In the given question, an x-ray of the shoulder joint is shown. As asked in the question, the shoulder joint is formed by the glenoid cavity and the head of the humerus which is marked as 1 and 3 in the given image.Hence, the answer to this question will be option C. The marked structure are following: Glenoid cavity Clavicle Head of the humerus Acromion process</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During a discussion on the anatomy of the given joint below, the fibrous capsule was discussed. Which of the following are the two extensions of the capsule as tubular sheath?", "options": [{"label": "A", "text": "Along the short head of biceps brachii and deep to supraspinatus.", "correct": false}, {"label": "B", "text": "Along the long head of biceps brachii and deep to supraspinatus.", "correct": false}, {"label": "C", "text": "Along the short head of the biceps brachii and deep to the subscapularis.", "correct": false}, {"label": "D", "text": "Along the long head of the biceps brachii and deep to the subscapularis.", "correct": true}], "correct_answer": "D. Along the long head of the biceps brachii and deep to the subscapularis.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683867120-QTDA106008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Along the long head of the biceps brachii and deep to the subscapularis. In the given question, the joint shown is the shoulder joint. It is a ball and socket type of joint. The fibrous capsule is attached to the glenoid labrum and anatomical neck of the humerus. The extension of the capsule as a tubular sheath is seen over the tendon of the long head of biceps brachii and just deep to the subscapularis known as the subscapularis bursa. Extensions of Fibrous Capsule of Shoulder joint Hence the answer to this question will be option D.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A,B & C. The extension of the capsule as a tubular sheath is seen over the tendon of the long head of biceps brachii and just deep to subscapularis known as subscapularis bursa, so Option A,B and C are incorrect answers.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 22-year-old male patient came in with a complaint of pain around the shoulder joint. He does not give any history of injury to the patient. On examination, the junior resident tells you that the joint is more laxed than a normal person's. Which of the following are the ligaments which stabilize the joint as shown in the image?", "options": [{"label": "A", "text": "1,2,3", "correct": true}, {"label": "B", "text": "1,3,4", "correct": false}, {"label": "C", "text": "2,4", "correct": false}, {"label": "D", "text": "1,4", "correct": false}], "correct_answer": "A. 1,2,3", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/questionImage-1690539881019-QTDA106009.jpg"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,2,3 In the given question, the ligaments which are marked are as follows. Glenoid labrum Articular Capsule Coraco-acromial ligament. Supraspinatus tendon The structure marked as 4 is the Supraspinatus tendon. It is a part of the rotator cuff and not a part of ligament support.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The following image was shown to you which shows the rotator cuff muscles around the shoulder joint. Which of the following statements regarding the rotator cuff muscles is not correct?", "options": [{"label": "A", "text": "The four muscles are subscapularis, supraspinatus, infraspinatus and teres minor.", "correct": false}, {"label": "B", "text": "The Subscapularis muscle is responsible for the external rotation of the shoulder joint.", "correct": true}, {"label": "C", "text": "Supraspinatus muscle is responsible for the initial 15 degrees of abduction.", "correct": false}, {"label": "D", "text": "Infraspinatus muscle externally rotates the shoulder joint.", "correct": false}], "correct_answer": "B. The Subscapularis muscle is responsible for the external rotation of the shoulder joint.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683867246-QTDA106010IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The Subscapularis muscle is responsible for the external rotation of the shoulder joint. The incorrect statement is option B as subscapularis is responsible for the internal rotation of the shoulder joint.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The four muscles marked are subscapularis, supraspinatus, infraspinatus and teres minor. The four muscles forming the rotator cuff are subscapularis, supraspinatus, infraspinatus and teres minor. Option: C. Supraspinatus muscle is responsible for the initial 15 degrees of abduction. The Supraspinatus muscle is responsible for initial abduction of 0 to 15 degrees. Option: D. Infraspinatus muscle externally rotates the shoulder joint. Infraspinatus muscle externally rotates the shoulder joint, is the correct statement about rotator cuff muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were posted in ortho OPD where a patient was being examined by the junior resident for movements at the shoulder joint. The following movement in the given image was performed by the patient labelled as A and B. Which of the following muscles given in the option represents the correct match responsible for the movement in A and B respectively?", "options": [{"label": "A", "text": "A-Ant fibres of deltoid, B- sternocostal fibres of the pectoralis major.", "correct": false}, {"label": "B", "text": "A- supraspinatus, B- anterior fibers of deltoid.", "correct": false}, {"label": "C", "text": "A- Clavicular fibres of the deltoid, B- post fibres of the deltoid.", "correct": true}, {"label": "D", "text": "A- teres major, B- post fibres of the deltoid.", "correct": false}], "correct_answer": "C. A- Clavicular fibres of the deltoid, B- post fibres of the deltoid.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683867794-QTDA106011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A- Clavicular fibres of the deltoid, B- post fibres of the deltoid. In the given question, figure A shows flexion movement at the shoulder joint for which the muscle acting is Anterior fiber of deltoid Clavicular fiber of pectoralis majo r Other supporting- coracobrachialis and short head of biceps brachii. Figure B shows extension movement which is done by: Posterior fibres of the deltoid Latissimus dorsi Other supporting muscles- teres major and long head of triceps. So Option C is the correct answer.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. A-Ant fibres of the deltoid, B- sternocostal fibres of the pectoralis major. The option is wrong because Sternocostal fibres are responsible for adduction at the shoulder joint. Option: B. A- supraspinatus, B- anterior fibers of deltoid. Option B is wrong because supraspinatus initiates the shoulder joint and anterior fibres of the deltoid are responsible for flexion movement. Option: D. A- teres major, B- post fibers of the deltoid. Option D is wrong because Teres major muscle is the extensor of the shoulder joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statements regarding the relation of structures to the shoulder joint is correct? A. Anteriorly- long head of biceps brachii and coracobrachialis. B. Superiorly- coracoacromial arch and supraspinatus. C. Posteriorly- teres minor and infraspinatus. D. Inferiorly- short head of triceps. Select the correct answer from the given below ciode:", "options": [{"label": "A", "text": "A, B", "correct": false}, {"label": "B", "text": "B, C", "correct": true}, {"label": "C", "text": "C, D", "correct": false}, {"label": "D", "text": "A, D", "correct": false}], "correct_answer": "B. B, C", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>B, C The relation of the shoulder joint is as follows: Shoulder joint Relations: Anteriorly- subscapularis, the short head of biceps brachii and coracobrachialis.( option A is wrong) Posteriorly- infraspinatus and teres minor.(option B is correct) Superiorly- coraco-acromian arch, long head of biceps brachii and supraspinatus. (option C is correct) Inferiorly- long head of triceps.(option D is wrong)</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 12-year-old boy came to your OPD with a complaint of inability to perform the following movement. Which of the following represents the correct order of muscle involved in performing the movement from starting to over the head? Supraspinatus Middle fibres of the deltoid. Serratus anterior Trapezius. Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1-> 2-> 3,4", "correct": true}, {"label": "B", "text": "1,2-> 3-> 4", "correct": false}, {"label": "C", "text": "2-> 1-> 3,4", "correct": false}, {"label": "D", "text": "3.4-> 2-> 1", "correct": false}], "correct_answer": "A. 1-> 2-> 3,4", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683867802-QTDA106013IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1-> 2-> 3,4 In the given question, the movement performed is abduction at the shoulder joint. The sequence of muscles from starting to overhead abduction i.e. from 0 degrees to >90 degrees involved are the following muscles in sequence. Supraspinatus- from 0-15 degrees. Anterior fibres of deltoid- 15- 90 degrees. Serratus anterior and trapezius (upper and lower fibres)- overhead abduction. Also, the rotation of the scapula helps in overhead abduction. Hence, the correct answer is option A.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options B, C and D. are not correct sequences for total abduction movement taking place at the shoulder joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 23 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 35 year old patient presented to the emergency department with sudden onset blindness in the right eye. On the fundus examination, there were no abnormalities seen. The clinician made a diagnosis of retrobulbar neuritis. This disease involves a cranial nerve passing through which of the following foramina?", "options": [{"label": "A", "text": "1", "correct": true}, {"label": "B", "text": "2", "correct": false}, {"label": "C", "text": "3", "correct": false}, {"label": "D", "text": "4", "correct": false}], "correct_answer": "A. 1", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393215829-QTDA072001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1 1 Refers to the optic canal where the optic nerve passes, The patient is suffering from retrobulbar neuritis that involves the optic nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Internal foramina of the skull Foramen Structures passing through the foramen ANTERIOR CRANIAL FOSSA Foramen cecum Emissary veins to nasal cavity Olfactory foramen in cribriform plate Olfactory nerves [I] MIDDLE CRANIAL FOSSA Optic canal Optic nerve [II]; ophthalmic artery Superior orbital fissure Oculomotor nerve [III]; trochlear nerve [IV]; ophthalmic division of the trigeminal nerve (V₁]; abducent nerve [VI]; ophthalmic veins Foramen rotundum Maxillary division of the trigeminal nerve [V 2 ] Foramen ovale Mandibular division of the trigeminal nerve [V 3 ]; lesser petrosal nerve Foramen spinosum Middle meningeal artery Hiatus for the greater petrosal nerve Greater petrosal nerve Hiatus for the lesser petrosal nerve Lesser petrosal nerve POSTERIOR CRANIAL FOSSA Foramen magnum End of brainstem/beginning of spinal cord; vertebral arteries; spinal roots of the accessory nerve; meninges Internal acoustic meatus Facial nerve [VII]; vestibulocochlear nerve [VIII]; labyrinthine artery Jugular foramen Glossopharyngeal nerve [IX]; vagus nerve [X]; accessory nerve [XI]; inferior petrosal sinus, sigmoid sinus (forming internal jugular vein) Hypoglossal canal Hypoglossal nerve [XII]; meningeal branch of the ascending pharyngeal artery Condylar canal Emissary's vein</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Foramen rotundum, transmits maxillary nerves. Option: C. 3 Foramen ovale, transmits mandibular nerve, accessory meningeal artery, lesser petrosal nerve, and emissary vein. Option: D. 4 Foramen spinosum, transmits nervus spinosus.</p>\n<p><strong>Extraedge:</strong></p><p>Pterion fractures The pterion is an important clinical point on the lateral aspect of the skull. To find the precise point of the pterion, an imaginary line 1 inch (2.5 em) above the zygomatic arch, and 1 inch (2.5 em) posterior to the lateral orbital margin will approximate this region. At the pterion, the frontal, parietal, greater wing of the sphenoid, and temporal bones come together. Importantly, deep in this structure is the middle meningeal artery. An injury to this point of the skull is extremely serious because damage to this vessel may produce a significant extradural hematoma, which can be fatal.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 30 year old male presented with discharge from the nose. When the patient puts a handkerchief on the nose it forms two rings like a target. On consulting the physician he asks the patient to get a beta 2 transferrin assay done. After biochemical confirmation, the doctor diagnosed it as CSF rhinorrhea. He ordered a CT scan of the head and a fracture of the anterior cranial fossa was seen. Which of the following does not form the floor of the anterior cranial fossa?", "options": [{"label": "A", "text": "Frontal Bone", "correct": false}, {"label": "B", "text": "Ethmoid bone", "correct": false}, {"label": "C", "text": "Greater wing of the sphenoid", "correct": true}, {"label": "D", "text": "Lesser wing of the sphenoid", "correct": false}], "correct_answer": "C. Greater wing of the sphenoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Greater wing of the sphenoid Greater wing of the sphenoid forms a part of the lateral border of the middle cranial fossa.</p>\n<p><strong>Highyeild:</strong></p><p>Anterior cranial fossa Parts of the frontal, ethmoid, and sphenoid bones form the anterior cranial fossa. Its floor is composed of frontal bone in the anterior and lateral direction, ethmoid bone in the midline, and two parts of the sphenoid bone posteriorly, the body (midline) and the lesser wings (laterally). Anterior cranial fossa</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - All the other bones mentioned in options A, B, and D form the floor of the anterior cranial fossa. Anterior cranial fossa</p>\n<p><strong>Extraedge:</strong></p><p>The anterior cranial fossa is above the nasal cavity and the orbits, and it is filled by the frontal lobes of the cerebral hemispheres.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 20 year old cab driver presented with a complaint of difficulty in seeing cars from his peripheral vision. He claims that the patient’s problems are gradually increasing since the past few months. Suspecting a pituitary adenoma the doctor orders an MRI brain. Which of the following structures lodge the pituitary gland?", "options": [{"label": "A", "text": "Sulcus Chiasmaticus", "correct": false}, {"label": "B", "text": "Tuberculum sellae", "correct": false}, {"label": "C", "text": "Sella turcica", "correct": true}, {"label": "D", "text": "Dorsum sellae", "correct": false}], "correct_answer": "C. Sella turcica", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sella turcica Pituitary gland lodges in the Sella turcica. The sella turcica forms a bony seat for the pituitary gland.</p>\n<p><strong>Highyeild:</strong></p><p>The sella turcica is a saddle-shaped depression in the body of the sphenoid bone of the human skull. It serves as a cephalometric landmark. The pituitary gland or hypophysis is located within the most inferior aspect of the sella turcica, the hypophyseal fossa. The pituitary gland sits in the sella turcica.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Sulcus chiasmatic-It refers to the optic groove, on each dose of it is the optic canal. Option: B. Tuberculum sellae separates the optic groove from the hypophyseal fossa Option: D. Dorsum sellae forms the back of Sella turcica.</p>\n<p><strong>Extraedge:</strong></p><p>The sella turcica is located in the sphenoid bone behind the chiasmatic groove and the tuberculum sellae. It belongs to the middle cranial fossa .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 20 year old alcoholic patient presented to the emergency department with a history of falls in the bathroom. The attending doctor ordered a CT scan of the head. It showed a fracture in the middle cranial fossa. Which of the following is unlikely to be seen in fracture of middle cranial fossa fracture?", "options": [{"label": "A", "text": "CSF Rhinorrhea", "correct": false}, {"label": "B", "text": "CSF Otorrhea", "correct": false}, {"label": "C", "text": "Battle sign", "correct": false}, {"label": "D", "text": "Black eye", "correct": true}], "correct_answer": "D. Black eye", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Black eye Raccoon eyes are seen in fractures of anterior cranial fossa fractures Fracture of the anterior cranial fossa may cause bleeding and discharge of cerebrospinal fluid through the nose. It may also cause a condition called black eye which is produced by seepage of blood into the eyelid, as the frontalis muscle has no bony origin.</p>\n<p><strong>Highyeild:</strong></p><p>CSF rhinorrhoea may be spontaneous, traumatic, or congenital Traumatic CSF rhinorrhoea is the most common type of CSF rhinorrhoea. It may be due to severe head injuries, or complications from neurosurgery. Spontaneous CSF rhinorrhoea is the most common acquired defect in the skull base bones (anterior cranial fossa) causing spontaneous nasal liquorrhea. Defects are often localized in the sphenoid bone and the ethmoid bone. sphenoid sinus (43%). ethmoid bone (29%). cribriform plate (29%). Congenital CSF rhinorrhoea is the least common type of CSF rhinorrhoea. It may be caused by problems in the embryological development of bones of the skull.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. CSF Rhinorrhea CSF rhinorrhea caused by anterior cranial fossa fractures, was more common than caused by temporal bone fractures. And fractures of ethmoidal bone and junction between cribriform and ethmoid were the most common cause of CSF rhinorrhea. If a fracture extending from the greater wing of the sphenoid to the sphenoid sinus occurs, a rhinorrhea may also occur, even though it is a middle fossa fracture. Option:B. CSF Otorrhea CSF (spinal fluid) otorrhea is a condition in which spinal fluid drains from the ear. Fracture of the middle cranial fossa produces: Bleeding and discharge of CSF through the ear. Bleeding through the nose or mouth may occur due to the involvement of the sphenoid bone. Option:C. Battle sign Battle Sign (also called Battle's Sign) is defined as bruising over the mastoid process. It is retro auricular or mastoid ecchymosis that is typically the result of head trauma.</p>\n<p><strong>Extraedge:</strong></p><p>Battle's sign , also known as mastoid ecchymosis , is an indication of a fracture of the middle cranial fossa of the skull. These fractures may be associated with underlying brain trauma. Battle's sign consists of bruising over the mastoid process as a result of extravasation of blood along the path of the posterior auricular artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 50 year old patient presented with headache, double vision, and nose bleeds. The doctor ordered an MRI brain and saw a tumor at the clivus. Surgery was planned for the removal of the tumor. The biopsy of the tumor revealed physaliferous cells indicating the tumor to be a chordoma. Chordoma is a tumor commonly occurring at the tailbone and clivus. Which of the following structures is not attached to the clivus?", "options": [{"label": "A", "text": "Apical ligament of dens", "correct": false}, {"label": "B", "text": "Cruciate ligament", "correct": false}, {"label": "C", "text": "Membrana tectoría", "correct": false}, {"label": "D", "text": "Transverse occipital ligament", "correct": true}], "correct_answer": "D. Transverse occipital ligament", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Transverse occipital ligament The transverse ligament of the atlas is a ligament that arches across the ring of the atlas (the topmost cervical vertebra, which directly supports the skull), and keeps the odontoid process in contact with the atlas.</p>\n<p><strong>Highyeild:</strong></p><p>The transverse ligament of the atlas is concave in front, convex behind, broader and thicker in the middle than at the ends, and firmly attached on either side to a small tubercle on the medial surface of the lateral mass of the atlas. As it crosses the odontoid process, a small fasciculus ( crus superius ) is prolonged upward, and another ( crus inferius ) downward, from the superficial or posterior fibers of the ligament. The former is attached to the basilar part of the occipital bone, in close relation with the membrana tectoria; the latter is fixed to the posterior surface of the body of the axis; hence, the whole ligament is named the cruciate ligament of the atlas. The transverse ligament divides the ring of the atlas into two unequal parts: of these, the posterior and larger serve for the transmission of the medulla spinalis and its membranes and the accessory nerves; the anterior and smaller contain the odontoid process.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Apical ligament of dens Option: B. Cruciate ligament Option: C. Membrana tectoría All the ligaments mentioned in options A,B, and C are attached to the clivus as shown in the image below.</p>\n<p><strong>Extraedge:</strong></p><p>The clivus , or Blumenbach clivus , is a bony part of the cranium at the base of the skull. It is a shallow depression behind the dorsum sellae of the sphenoid bone. It slopes gradually to the anterior part of the basilar occipital bone at its junction with the sphenoid bone. It extends to the foramen magnum. It is related to the pons and the abducens nerve (CN VI).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A comatose patient was brought to the emergency department. The patient’s tongue kept falling back so the attending physician put a Guedel airway into the patient. The intern alongside the physician asked him, which muscle prevents the tongue from falling back and the physician replied it is a muscle known as genioglossus which protrudes the tongue. Genioglossus is known as the safety muscle of the tongue and is supplied by the hypoglossal nerve. Which of the following foramina transmits the affected nerve?", "options": [{"label": "A", "text": "1", "correct": true}, {"label": "B", "text": "2", "correct": false}, {"label": "C", "text": "3", "correct": false}, {"label": "D", "text": "4", "correct": false}], "correct_answer": "A. 1", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393217733-QTDA072006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1 This represents the hypoglossal canal from which the hypoglossal nerve passes.</p>\n<p><strong>Highyeild:</strong></p><p>Hypoglossal nerve [XII] Somatic motor - all muscles of the tongue except palatoglossus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. 2 It is the aqueduct of vestibule Option: C. 3 It is the internal acoustic meatus from which the 6th nerve, 7th nerve, and labyrinthine artery pass Option: D. 4 It is the jugular foramen that transmits the 9th 10th 11th cranial nerve and sigmoid sinus</p>\n<p><strong>Extraedge:</strong></p><p>Cranial nerve lesions Cranial Nerve Clinical Findings Example of Lesion Olfactory nerve [1] Loss of smell (anosmia) Injury to the cribriform plate; congenital absence Optic nerve [II] Blindness/visual field abnormalities, loss of pupillary constriction Direct trauma to the orbit; disruption of the optic pathway Oculomotor nerve [III] Dilated pupil, ptosis, loss of normal pupillary reflex, the eye moves down inferiorly and laterally (down and out) Pressure from an aneurysm arising from the posterior communicating, posterior cerebral, or superior cerebellar artery; pressure from a herniating cerebral uncus (false localizing sign); cavernous sinus mass or thrombosis Trochlear nerve [IV] Inability to look inferiorly when the eye is adducted (down and in) Along the course of the nerve around the brainstem; orbital fracture Trigeminal nerve [V] Loss of sensation and pain in the region supplied by the three divisions of the nerve over the face; loss of motor function of the muscles of mastication on the side of the lesion Typically, in the region of the trigeminal ganglion, though local masses around the foramina through which the divisions pass can produce symptoms Abducent nerve [VI] The inability of lateral eye movement Brain lesion or cavernous sinus lesion extending onto the orbit Facial nerve [VII] Paralysis of facial muscles Abnormal taste sensation from the anterior two-thirds of the tongue and dry conjunctivae Paralysis of contralateral facial muscles below the eye Damage to the branches within the parotid gland Injury to the temporal bone; viral inflammation of nerve Brainstem injury Vestibulocochlear nerve [VIII] Progressive unilateral hearing loss and tinnitus (ringing in the ear) Tumor at the cerebellopontine angle Glossopharyngeal nerve [IX] Loss of taste to the posterior one-third of the tongue and sensation of the soft palate Brainstem lesion; penetrating neck injury Vagus nerve [X] Soft palate deviation with a deviation of the uvula to the normal side; vocal cord paralysis Brainstem lesion; penetrating neck injury Accessory nerve [XI] Paralysis of sternocleidomastoid and trapezius muscles Penetrating injury to the posterior triangle of the neck Hypoglossal nerve [XII] Atrophy of ipsilateral muscles of the tongue and deviation toward the affected side; speech disturbance Penetrating injury to the neck and skull base pathology</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 20 year old patient presented with ophthalmoplegia, pain, and paresthesia along the forehead region and exophthalmos. The doctor made a diagnosis of superior orbital fissure syndrome. Which of the following structures does not pass a superior orbital fissure?", "options": [{"label": "A", "text": "Optic Nerve", "correct": true}, {"label": "B", "text": "Nasociliary nerve", "correct": false}, {"label": "C", "text": "Oculomotor nerve", "correct": false}, {"label": "D", "text": "Abducens nerve", "correct": false}], "correct_answer": "A. Optic Nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Optic Nerve The optic nerve passes through the tendon's ring of zinn via the optic canal, but it does not pass through the superior orbital fissure.</p>\n<p><strong>Highyeild:</strong></p><p>Mnemonics Long Fissures Seem To Store Only Nerves, Instead Of Arteries, Including Ophthalmic Veins The order of the contents passing through the superior orbital fissure from superior to inferior: L: lacrimal nerve (branch of CN V1) F: frontal nerve (branch of CN V1) S: superior ophthalmic vein (tributary to cavernous sinus) T: trochlear nerve (CN IV) SO: superior division of the oculomotor nerve (CN III) N: nasociliary nerve (branch of CN V1) IO: inferior division of the oculomotor nerve (CN III) A: abducens nerve (CN VI) IOV: inferior ophthalmic vein (tributary to both cavernous sinus and pterygoid venous plexus) Structures passing through the superior orbital fissure</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B, C & D. All the other 3 structures pass through the superior orbital fissure.</p>\n<p><strong>Extraedge:</strong></p><p>The superior orbital fissure is a foramen or cleft of the skull between the lesser and greater wings of the sphenoid bone. It gives passage to multiple structures, including the oculomotor nerve, trochlear nerve, ophthalmic nerve, abducens nerve, ophthalmic veins, and sympathetic fibers from the cavernous plexus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A neonate presented with cyanosis. The presentation is such that when the child cries the cyanosis disappears but when the child is silent the cyanosis reappears. Seeing this the attending physician diagnosed the child as choanal atresia. Choanal atresia is a condition in which there is a block of posterior nares due to soft tissue bone or both. Which of the following bones do not form the boundary of posterior nares?", "options": [{"label": "A", "text": "Vomer", "correct": false}, {"label": "B", "text": "Body of Sphenoid", "correct": false}, {"label": "C", "text": "Lesser wing of the sphenoid", "correct": true}, {"label": "D", "text": "Palatine bone", "correct": false}], "correct_answer": "C. Lesser wing of the sphenoid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lesser wing of the sphenoid The lesser wing of the sphenoid does not form a part of the posterior nares.</p>\n<p><strong>Highyeild:</strong></p><p>Choana is the posterior nasal aperture. The posterior nasal apertures (choanae) are separated from each other by the posterior border of the vomer. Choana is a space bounded as follows : Anteriorly and inferiorly by the horizontal plate of the palatine bone, superiorly and posteriorly by the sphenoid bone laterally by the medial pterygoid plates. Posterior nasal aperture</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - The posterior nasal aperture consists of the following bones. Option: A. The posterior nasal apertures (choanae) are separated from each other by the posterior border of the vomer. Option: B. Body of sphenoid and Vaginal process of sphenoid at the floor Option: D. Palatine bone-It forms the lateral border of the internal nares</p>\n<p><strong>Extraedge:</strong></p><p>The pyriform or nasal aperture, is the pear-shaped bony inlet of the nose formed by the nasal and maxillary bones. It forms the boundary between the anterior nasal vestibule (of the nasal cavity) and the posterior nasal cavity proper. The maxillary spines mark the inferior margin of the pyriform aperture.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The Eustachian tube is a narrow passage leading from the pharynx to the cavity of the middle ear permitting the equalization of pressure on each side of the eardrum. In case of a cough/cold Eustachian tube often gets blocked so during rapid ascent or descent the patient presents with ear pain. The eustachian tube passes through which of the following structures located at the base of the skull?", "options": [{"label": "A", "text": "Canaliculus Innominatus", "correct": false}, {"label": "B", "text": "Foramen of Vesalius", "correct": false}, {"label": "C", "text": "Foramen spinosum", "correct": false}, {"label": "D", "text": "Sulcus tubae", "correct": true}], "correct_answer": "D. Sulcus tubae", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sulcus tubae Sulcus tubae is the groove between the posteromedial margin of the greater wing of the sphenoid and the petrous temporal bone. It lodges the cartilaginous part of the Eustachian tube.</p>\n<p><strong>Highyeild:</strong></p><p>The sulcus tubae, which is the attachment site of the cartilaginous part of the eustachian tube to the cranial base, is located on the extracranial surface of the sphenopetrosal fissure, anterolateral to the foramen lacerum and the carotid canal, and posteromedial to the foramina ovale and spinosum. Norma basalis showing the passage of main nerves and arteries and sulcus tubae</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Canaliculus innominate- it is situated between foramen ovale and foramen spinous Option: B. Foramen of Vesalius- Also known as emissary sphenoidal foramen is situated between foramen ovale and scaphoid fossa. Internally it opens between foramen ovale and the foramen rotundum Option: C. Foramen spinosum- It transmits middle meningeal vessels and nervus spinous</p>\n<p><strong>Extraedge:</strong></p><p>Eustachian tube , also known as the auditory tube or pharyngotympanic tube , is a tube that links the nasopharynx to the middle ear, of which it is also a part. In adult humans, the Eustachian tube is approximately 35 mm (1.4 in) long and 3 mm (0.12 in) in diameter.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient presents to the Ent department with pain and tenderness behind the ear. On history taking and examination the physician concluded that the patient was suffering from citelli’s abscess. It is a condition where pus from mastoid tip trickles down along the posterior belly of digastric muscle to the occipital and cervical region. Which of the following sites accurately describes the location of attachment of the posterior belly of digastric muscle?", "options": [{"label": "A", "text": "1", "correct": true}, {"label": "B", "text": "2", "correct": false}, {"label": "C", "text": "3", "correct": false}, {"label": "D", "text": "4", "correct": false}], "correct_answer": "A. 1", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393248830-QTDA073003IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1 is the site of attachment of the posterior belly of digastric muscle, as shown in the image below. Inferior view of skull, showing muscular attachments</p>\n<p><strong>Highyeild:</strong></p><p>The digastricus (digastric muscle) consists of two muscular bellies united by an intermediate rounded tendon. The posterior belly, longer than the anterior belly, arises from the mastoid notch which is on the inferior surface of the skull, medial to the mastoid process of the temporal bone. It lies posterior to the parotid gland and the facial nerve. The mastoid notch is a deep groove between the mastoid process and the styloid process. The mastoid notch is also referred to as the digastric groove or the digastric fossa. The posterior belly is supplied by the digastric branch of the facial nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options: B. It is the attachment site for Sternocleidomastoid. Options: C. It is the attachment site for Trapezius. Options: D. It is the attachment site for Semispinalis capitis.</p>\n<p><strong>Extraedge:</strong></p><p>The anterior belly arises from a depression on the inner side of the lower border of the mandible called the digastric fossa of the mandible, close to the symphysis, and passes downward and backward. The anterior body is supplied by the trigeminal via the mylohyoid nerve, a branch of the inferior alveolar nerve, itself a branch of the mandibular division of the trigeminal nerve. It originates from the first pharyngeal arch.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 15-year-old boy presented with anhydrous enophthalmos ptosis and miosis. The physician diagnosed the patient as having Horner's syndrome. It usually occurs due to defects in sympathetic fibers of the T1 nerve root carried along with the internal carotid artery. Carotid artery traverses the upper part of the foramina at the base of the skull. Which of the following structures pass through this foramen?", "options": [{"label": "A", "text": "Accessory Meningeal Artery", "correct": false}, {"label": "B", "text": "Meningeal branch of ascending pharyngeal artery", "correct": true}, {"label": "C", "text": "Posterior palatine nerves", "correct": false}, {"label": "D", "text": "Middle meningeal artery", "correct": false}], "correct_answer": "B. Meningeal branch of ascending pharyngeal artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Meningeal branch of ascending pharyngeal artery Foramen lacerum is filled with cartilage along with emissary vein and meningeal branch of ascending pharyngeal artery.</p>\n<p><strong>Highyeild:</strong></p><p>The structures passing through the foramen lacerum: During life, the lower part of the foramen is filled with cartilage, and no significant structure passes through the whole length of the canal, except for the meningeal branch of the ascending pharyngeal artery and an emissary vein from the cavernous sinus. Structures related to the foramen lacerum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Accessory meningeal artery passes through foramen ovale. Structures passing through foramen ovale are Mandibular nerve Accessory meningeal artery Lesser petrosal nerve Emissary's vein Option: C. Posterior palatine nerves and middle palatine nerves pass through lesser palatine foramina Option: D. Middle meningeal artery passes through foramen spinous along with a meningeal branch of mandibular nerve and posterior trunk of middle meningeal vein</p>\n<p><strong>Extraedge:</strong></p><p>The upper part of the foramen lacerum, is traversed by the internal carotid artery with venous and sympathetic plexuses around it. In the anterior part of the foramen, the greater petrosal nerve unites with the deep petrosal nerve to form the nerve of the pterygoid canal (Vidian’s nerve) which leaves the foramen by entering the pterygoid canal in the anterior wall of the foramen lacerum .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Foramen magnum is the largest foramen of the skull and is a part of occipital bone. It is bounded anteriorly by basilar part of occipital bone anterolaterally by occupied condyles and posteriorly by occipital bone. Which of the following structures does not pass through foramen magnum?", "options": [{"label": "A", "text": "Anterior and posterior spinal arteries", "correct": false}, {"label": "B", "text": "Cranial part of spinal accessory nerve", "correct": true}, {"label": "C", "text": "Fourth part of vertebral artery", "correct": false}, {"label": "D", "text": "First tooth of Ligamentum denticulatum", "correct": false}], "correct_answer": "B. Cranial part of spinal accessory nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cranial part of spinal accessory nerve Spinal part of spinal accessory nerve passes through foramen magnum</p>\n<p><strong>Highyeild:</strong></p><p>Structures passing through foramen magnum Through the narrow anterior part: Apical ligament of dens Vertical band of cruciate ligament Membrana tectoria Through wider posterior part: Lowest part of medulla oblongata Three meninges. Through the subarachnoid space pass: Spinal accessory nerves Vertebral arteries Sympathetic plexus around the vertebral arteries Posterior spinal arteries Anterior spinal artery. Structures passing through foramen magnum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Anterior and posterior spinal arteries Option: B. Cranial part of spinal accessory nerve Option: D. The first tooth of Ligamentum denticulatum Anterior and posterior spinal arteries, cranial part of spinal accessory nerve, and first tooth of Ligamentum denticulatum all pass through the foramen magnum.</p>\n<p><strong>Extraedge:</strong></p><p>Diploic veins Vein Foramen Drainage 1. Frontal diploic vein Supraorbital foramen Drain into supraorbital vein 2. Anterior temporal or parietal diploic vein In the greater wing of the sphenoid Sphenoparietal sinus or in the anterior deep temporal vein 3. Posterior temporal or parietal diploic vein Mastoid foramen Transverse sinus 4. Occipital diploic vein (largest) Foramen in occipital bone Occipital vein or confluence of sinuses 5. Small unnamed diploic veins Pierce inner table of the skull close to the margins of superior sagittal sinus Venous lacunae</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Dysphagia and loss of gag reflex. The patient also had paralysis of the sternocleidomastoid and trapezius muscles. After a thorough clinical examination, a diagnosis of Vernet syndrome/Jugular foramen syndrome was made. Which of the following with respect to the jugular foramen Is false?", "options": [{"label": "A", "text": "Anterior part of the Jugular foramen transmits inferior petrosal sinus.", "correct": false}, {"label": "B", "text": "Middle part of Jugular foramen transmits VII, IX, X cranial Nerve.", "correct": true}, {"label": "C", "text": "Posterior part of the Jugular foramen transmits sigmoid sinus draining into the internal jugular vein", "correct": false}, {"label": "D", "text": "Glossopharyngeal notch near the medial end of the jugular foramen lodges the inferior ganglion of the glossopharyngeal nerve.", "correct": false}], "correct_answer": "B. Middle part of Jugular foramen transmits VII, IX, X cranial Nerve.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Middle part of Jugular foramen transmits VII, IX, X cranial Nerve.</p>\n<p><strong>Highyeild:</strong></p><p>The Jugular Foramen Transmits The Following Structures : Through the anterior part: Inferior petrosal sinus. Meningeal branch of the ascending pharyngeal artery Through The Middle Part: IX, X, and XI cranial nerves. Through the posterior part: Internal Jugular Vein Meningeal branch of the occipital artery. Structure passing through Jugular Foramen</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Anterior part of Jugular foramen transmits inferior petrosal sinus. The Jugular Foramen Transmits the Inferior petrosal sinus through the anterior part. Option: C. Posterior part of the Jugular foramen transmits sigmoid sinus draining into the internal jugular vein The Jugular Foramen Transmits sigmoid sinus draining into the internal jugular vein through the posterior part. Option: D. The glossopharyngeal notch near the medial end of the jugular foramen lodges the inferior ganglion of the glossopharyngeal nerve. The glossopharyngeal notch near the medial end of the jugular foramen lodges the inferior ganglion of the glossopharyngeal nerve.</p>\n<p><strong>Extraedge:</strong></p><p>The glossopharyngeal notch near the medial end of the jugular foramen lodges the inferior ganglion of the glossopharyngeal nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient presented with sudden sharp nerve-like pain in the jaw bone, back of the throat, and base of the tongue. AP and Lateral radiographs of the patient showed an elongated calcified styloid process confirming the diagnosis of Eagle syndrome. Which of the following is false about the structures attached to the styloid process?", "options": [{"label": "A", "text": "Styloglossus muscle arising from the anterior surface of styloid is supplied by IXth cranial nerve", "correct": true}, {"label": "B", "text": "Stylopharyngeus muscle arises from the base of styloid process and inserts on the posterior border of lamina of thyroid cartilage", "correct": false}, {"label": "C", "text": "Stylohyoid ligament extends from the tip of styloid process and attaches to lesser cornu of hyoid bone", "correct": false}, {"label": "D", "text": "Facial nerve crosses the base of styloid process laterally and emerges from stylomastoid foramen", "correct": false}], "correct_answer": "A. Styloglossus muscle arising from the anterior surface of styloid is supplied by IXth cranial nerve", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393249806-QTDA073007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Styloglossus muscle arising from the anterior surface of styloid is supplied by IXth cranial nerve Styloglossus muscle is supplied by the hypoglossal nerve.</p>\n<p><strong>Highyeild:</strong></p><p>The five attachments resemble the reins of a chariot. Two of these reins (ligaments) are non adjustable, whereas the other three (muscles) are adjustable and are controlled each by a separate cranial nerve—seventh, ninth and twelfth nerves. The stylomandibular ligament is attached laterally to the styloid process above and angle of mandible below. The stylohyoid ligament extends from the tip of the styloid process to the lesser cornua of the hyoid bone. Three muscles attached to the styloid process are innervated by three nerves. Styloglossus muscle is supplied by the hypoglossal nerve. Stylopharyngeus muscle is supplied by the glossopharyngeal nerve. Stylohyoid muscle Is supplied by the facial nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Stylopharyngeus muscle arises from base of styloid process and inserts on posterior border of lamina of thyroid cartilage Stylopharyngeus muscle arises from the medial side of the base of the temporal styloid process and inserts on the posterior border of the lamina of thyroid cartilage. Option: C. Stylohyoid ligament extends from tip of styloid process and attaches to lesser cornu of hyoid bone The stylohyoid ligament is a ligament that connects the hyoid bone to the temporal styloid process (of the temporal bone of the skull). The stylohyoid ligament connects the lesser horn of the hyoid bone to the styloid process of the temporal bone of the skull. Option: D. Facial nerve crosses the base of the styloid process laterally and emerges from the stylomastoid foramen The stylomastoid foramen is a small, round opening located on the inferolateral aspect of the temporal bone, between the root of the styloid process and the mastoid process. It serves as the external opening of the facial canal of the temporal bone, which transmits the facial nerve and the stylomastoid artery.</p>\n<p><strong>Extraedge:</strong></p><p>The stylohyoid ligament is a ligament that connects the hyoid bone to the temporal styloid process (of the temporal bone of the skull). The stylohyoid ligament connects the lesser horn of the hyoid bone to the styloid process of the temporal bone of the skull. Option: D. Facial nerve crosses the base of the styloid process laterally and emerges from the stylomastoid foramen The stylomastoid foramen is a small, round opening located on the inferolateral aspect of the temporal bone, between the root of the styloid process and the mastoid process. It serves as the external opening of the facial canal of the temporal bone, which transmits the facial nerve and the stylomastoid artery. The stylopharyngeus is the medial-most and most vertical of the three styloid muscles. The muscle is situated between the external carotid artery and the internal carotid artery. On the lateral pharyngeal wall, it is situated posterior to the superior constrictor muscle, and anterior to the buccopharyngeal fascia. The glossopharyngeal nerve runs on the lateral side of this muscle and crosses over it to reach the tongue. The styloid apparatus: Lateral view</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which one of the following muscles has the action of flexing the proximal phalanx of the great toe?", "options": [{"label": "A", "text": "Dorsal Interossei", "correct": false}, {"label": "B", "text": "Plantar interossei", "correct": false}, {"label": "C", "text": "Flexor digitorum brevis", "correct": false}, {"label": "D", "text": "Flexor hallucis brevis", "correct": true}], "correct_answer": "D. Flexor hallucis brevis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Flexor hallucis brevis Flexor hallucis brevis flexes the proximal phalanx of the great toe.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - Dorsal interossei abduct the toes relative to the longitudinal axis of the second metatarsal. They also flex the metatarsophalangeal joints and extend the interphalangeal joints of the lateral four toes. The great and fifth toes have their own abductors. Option B- Plantar interossei adduct the third, fourth and fifth toes, flex the metatarsophalangeal joints and extend the interphalangeal joints . Option C - Flexor digitorum brevis flexes the lateral four toes at the proximal interphalangeal joint, with equal effect in any position of the ankle joint.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient came to the clinic complaining of pain over the medial calcaneal process, exacerbated by the passive ankle or great toe flexion. Diagnosis of plantar fasciitis is made. What is the cause of plantar fasciitis?", "options": [{"label": "A", "text": "Compression of the medial plantar nerve at the knot of Henry", "correct": false}, {"label": "B", "text": "Severe inversion of the ankle", "correct": false}, {"label": "C", "text": "Morton's neuroma", "correct": false}, {"label": "D", "text": "Compression of lateral plantar nerve by deep fascia", "correct": true}], "correct_answer": "D. Compression of lateral plantar nerve by deep fascia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Compression of lateral plantar nerve by deep fascia Compression of the first branch of the lateral plantar nerve (Baxter’s nerve) by the deep fascia that covers abductor hallucis has been implicated as a possible cause of plantar fasciitis. Lateral plantar compression causes Plantar fasciitis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A- The medial plantar nerve can be compressed at the 'knot of Henry,' which is the point where the tendon of flexor hallucis longus crosses deep to the tendon of flexor digitorum longus, to reach its medial side in the sole of the foot. Option B- Superficial fibular nerve can be damaged in severe ankle inversion injuries. Option C- Entrapment of the third common digital nerve as it passes deep to the intermetatarsal ligament of the third (or less commonly the second) web space can result in Morton's neuroma , which is probably the most common form of nerve entrapment in the foot.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A muscle which abducts the toes relative to the longitudinal axis of the second metatarsal. They also flex the metatarsophalangeal joints and extend the interphalangeal joints of the lateral four toes. Denervation of this muscle leads to claw-toe deformity. Find the muscle and nerve involved in this condition.", "options": [{"label": "A", "text": "Flexor digitorum brevis is innervated by the medial plantar nerve", "correct": false}, {"label": "B", "text": "Dorsal interossei supplied by the deep branch of the lateral plantar nerve", "correct": true}, {"label": "C", "text": "Flexor hallucis brevis is supplied by the medial plantar nerve", "correct": false}, {"label": "D", "text": "Abductor digiti minimi and flexor accessorius are innervated by the lateral plantar nerve", "correct": false}], "correct_answer": "B. Dorsal interossei supplied by the deep branch of the lateral plantar nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Dorsal interossei supplied by the deep branch of the lateral plantar nerve Dorsal interossei abduct the toes relative to the longitudinal axis of the second metatarsal. They also flex the metatarsophalangeal joints and extend the interphalangeal joints of the lateral four toes. The great and fifth toes have their own abductors.</p>\n<p><strong>Highyeild:</strong></p><p>Lateral plantar nerve branches</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A- Flexor digitorum brevis flexes the lateral four toes at the proximal interphalangeal joint, with equal effect in any position of the ankle joint. Option C- Flexor hallucis brevis flexes the proximal phalanx of the great toe. Option D- Abductor digiti minimi lies along the lateral border of the foot, and its medial margin is related to the lateral plantar vessels and nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following is the muscle of the third layer of plantar foot muscle?", "options": [{"label": "A", "text": "Flexor Hallucis Brevis", "correct": true}, {"label": "B", "text": "Lumbrical muscles", "correct": false}, {"label": "C", "text": "Flexor digitorum brevis", "correct": false}, {"label": "D", "text": "Plantar interossei", "correct": false}], "correct_answer": "A. Flexor Hallucis Brevis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Flexor Hallucis Brevis The t hird layer of the foot contains the shorter intrinsic muscles of the toes, i.e. flexor hallucis brevis, adductor hallucis and flexor digitiminimi brevis.</p>\n<p><strong>Highyeild:</strong></p><p>Third layer Sole muscles</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B - The second layer consists of flexor accessories and the four lumbrical muscles. Option C- This superficial layer includes abductor hallucis, abductor digit minima and flexor digitorum brevis Option D- The fourth layer of muscles of the foot consists of the plantar and dorsal interossei.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The arches of the foot are responsible for smoothly carrying out standing, running and walking. Which bones are involved in the formation of the transverse arch?", "options": [{"label": "A", "text": "Calcaneus, the cuboid and the fourth and fifth metatarsals", "correct": false}, {"label": "B", "text": "Bases of the five metatarsals, the cuboid and the cuneiforms", "correct": true}, {"label": "C", "text": "Calcaneus, talar head, navicular, the three cuneiforms and the medial three metatarsals", "correct": false}, {"label": "D", "text": "Talus and metatarsal alone", "correct": false}], "correct_answer": "B. Bases of the five metatarsals, the cuboid and the cuneiforms", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Bases of the five metatarsals, the cuboid and the cuneiforms The bones involved in the transverse arch are the bases of the five metatarsals, the cuboid and the cuneiforms. The transverse arch is located in the coronal plane of the foot. It is formed by the metatarsal bases, the cuboid and the three cuneiform bones. Transverse arch of foot</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A - The lateral longitudinal arch is a much less pronounced arch than the medial one. The bones making up the lateral longitudinal arch are the calcaneus, the cuboid and the fourth and fifth metatarsals; they contribute little to the arch in terms of stability Option C - The medial margin of the foot arches up between the heel proximally and the medial three metatarsophalangeal joints to form a visible arch. It is made up of the calcaneus, talar head, navicular, the three cuneiforms and the medial three metatarsals. Option D- Talus and metatarsal alone do not contribute to transverse arch.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "When a 4-year-old school child comes for the first visit you notice the child has flat feet. Along with that, the feet are flexible and cause minimal problems. What is this condition called?", "options": [{"label": "A", "text": "Pathological Pes Planus", "correct": false}, {"label": "B", "text": "Physiological pes planus", "correct": true}, {"label": "C", "text": "Pes cavus", "correct": false}, {"label": "D", "text": "Global cavus", "correct": false}], "correct_answer": "B. Physiological pes planus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Physiological pes planus Pes planus denotes an excessively flat foot. There is no precise degree of flatness that defines pes planus but it may be either physiological or pathological. In physiological pes planus, the feet are flexible and rarely problematic. There is a high prevalence in children of preschool age. In the age group 2-6 years , normal arch volumes in the sitting and standing positions correlate with the height of the navicular (lowest palpable medial projection of the navicular to the floor)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A- Pathological pes planus is often associated with stiffness and pain. The windlass (or 'Jack's great toe' ) test involves passively dorsiflexing the great toe at the metatarsophalangeal joint. This tightens the plantar aponeurosis and, in flexible pes planus, results in the accentuation of the medial longitudinal arch. In pathological pes planus, no accentuation of the arch is seen. Option C- Pes cavus denotes an excessively higharched foot. Most cases arise due to a neurological disorder (e. Charcot-Marie-Tooth disease, tethered spinal cord, poliomyelitis ). According to the anatomical location of the deformity, pes cavus may be classified into hindfoot, midfoot or forefoot cavus. Option D- When pes cavus involves all three parts of the foot, it is called 'global' cavus .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which muscle flexes the lateral four toes at the proximal interphalangeal joint, with equal effect in any position of the ankle joint?", "options": [{"label": "A", "text": "Dorsal Interossei", "correct": false}, {"label": "B", "text": "Plantar interossei", "correct": false}, {"label": "C", "text": "Flexor digitorum brevis", "correct": true}, {"label": "D", "text": "Flexor hallucis brevis", "correct": false}], "correct_answer": "C. Flexor digitorum brevis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Flexor digitorum brevis Flexor digitorum brevis flexes the lateral four toes at the proximal interphalangeal joint , with equal effect in any position of the ankle joint. Flexor digitorum brevis muscle</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A- Dorsal interossei abduct the toes relative to the longitudinal axis of the second metatarsal. They also flex the metatarsophalangeal joints and extend the interphalangeal joints of the lateral four toes. The great and fifth toes have their own abductors. Option B- Plantar interossei adduct the third, fourth and fifth toes, flex the metatarsophalangeal joints and extend the interphalangeal joints. Option D- flexor hallucis brevis Flexor hallucis brevis flexes the proximal phalanx of the great toe.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "All are true about the marked structure in the given image except:", "options": [{"label": "A", "text": "formed from paraxial mesoderm", "correct": false}, {"label": "B", "text": "develops between days 20-30 and is referred to as the somite period", "correct": false}, {"label": "C", "text": "initial number of somites formed is 42-44 pairs", "correct": false}, {"label": "D", "text": "occipital somites are 12 in number", "correct": true}], "correct_answer": "D. occipital somites are 12 in number", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681233958-QTDA014001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>occipital somites are 12 in number The marked structure in the image is somites Occipital somites are 4 pairs, i.e. 8 in number High Yield The paraxial mesoderm undergoes segmentation to form somatomeres and somites.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. formed from paraxial mesoderm The paraxial mesoderm becomes segmented to form 40–45 pairs of somites that lie on either side of the developing neural tube and notochord. Option B. develops between days 20-30 and is referred to as the somite period The somites appear between the 20th and 30th day of development. Hence, the 4th week of development is known as a somite period of development. Option C. initial number of somites formed are 42-44 pairs By the end of the fifth week, about 42 days, 44 pairs of somites are formed in the human embryo. Out of these 4 are occipital, 8 are cervical, 12 are thoracic, 5 are lumbar, 5 are sacral, and from 8 to 10 are coccygeal. The somites form visible surface elevations on either side of the midline. Therefore, all Explanation for incorrect options:- about somites are true-a) formed from paraxial mesoderm, b) develops between days 20-30 and is referred to as the somite period and c) an initial number of somites formed are 42-44 pairs.</p>\n<p><strong>Extraedge:</strong></p><p>The first pair of somatomeres appears in the cephalic region of the embryo and their formation proceeds craniocaudally. Each somatomere consists of mesodermal cells arranged in concentric whorls around the centre of the unit. Somatomeres 1–7, which are located from cephalic to otic vesicle, do not condense to form somites but contribute to the mesoderm of the head and neck region, which forms all the striated muscles in this region. The remaining somatomeres located caudal to otic vesicle condense to form well-defined cubical blocks called somites .</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The total number of thoracic somites:", "options": [{"label": "A", "text": "4 Pairs", "correct": false}, {"label": "B", "text": "8 pairs", "correct": false}, {"label": "C", "text": "12 pairs", "correct": true}, {"label": "D", "text": "5 pairs", "correct": false}], "correct_answer": "C. 12 pairs", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>12 pairs Thoracic somites are 12 pairs.</p>\n<p><strong>Highyeild:</strong></p><p>The first occipital and the last five to seven coccygeal somites later disappear, whereas the remaining somites form the axial skeleton.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. 4 Pairs Occipital somites are 4 pairs Option B. 8 pairs Cervical somites are 8 pairs. Option D. 5 pairs Sacral somites are 5 pairs Lumbar somites are 5 pairs Coccygeal somites are 8- 10 pairs</p>\n<p><strong>Extraedge:</strong></p><p>The vertebral column is formed from the sclerotomes of the somites.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Most cranial structure in the embryonic plate before folding of the embryo:", "options": [{"label": "A", "text": "Septum Transversum", "correct": true}, {"label": "B", "text": "primordial heart", "correct": false}, {"label": "C", "text": "both a & b", "correct": false}, {"label": "D", "text": "none of the above", "correct": false}], "correct_answer": "A. Septum Transversum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Septum Transversum The most cranial structure in the embryonic plate before the folding of the embryo is the septum transversum. High Yield The septum transversum is made of intraembryonic mesoderm that lies cranial to the pericardial cavity. After the formation of the head fold, it lies caudal to the pericardium and heart. The liver and the diaphragm develop in relation to the septum transversum.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Most cranial structure in the embryonic plate after folding of the embryo is b) primordial heart Hence c) both a & b and d) none of the above is incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>The pericardial cavity is derived from part of the intraembryonic coelom that lies cranial to the prochordal plate. The developing heart lies ventral to the cavity. After the formation of the head fold the pericardial cavity lies ventral to the foregut; and the developing heart is dorsal to the pericardial cavity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The following congenital anomaly is due to:", "options": [{"label": "A", "text": "Persistent Primitive Streak", "correct": true}, {"label": "B", "text": "Cloacal membrane", "correct": false}, {"label": "C", "text": "Notochord", "correct": false}, {"label": "D", "text": "Closure of the caudal neuropore", "correct": false}], "correct_answer": "A. Persistent Primitive Streak", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681234064-QTDA014004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Persistent Primitive Streak Sacrococcygeal teratoma occurs due to the PGCs (primordial germ cells) in the persistent caudal end of the primitive streak. Sometimes, remnants of the primitive streak persist in the sacrococcygeal region. These clusters of pluripotent cells proliferate and form tumours, known as sacrococcygeal teratomas, which commonly contain tissues derived from all three germ layers. It is a tumour that develops before birth and grows from a baby's coccyx, more commonly known as the tailbone.</p>\n<p><strong>Highyeild:</strong></p><p>Sacrococcygeal teratoma is the most common tumour in newborns, occurring with a frequency of 1 in 37,000. Teratomas may also arise from primordial germ cells that fail to migrate to the gonadal ridge.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Cloacal membrane Patients with cloacal malformation may have abnormal development in other organ systems. These abnormalities may affect the spine (Vertebral) or cause Anorectal malformations, heart defects (Cardiac), Trachea-Esophageal fistula and/or atresia, or Renal and Limb abnormalities Option C. Notochord The above case is Sacrococcygeal teratoma that occurs due to the PGCs (primordial germ cells) in the persistent caudal end of the primitive streak and not due to notochord deformity. Split notochord syndrome is a rare neural tube malformation involving the brain, spinal cord, and vertebral column. Option D . Closure of caudal neuropore The caudal neuropore closes during stage 12, generally when 25 somatic pairs are present. The site of final closure is at the level of future somite 31, which corresponds to the second sacral vertebral level. Non-closure of the neuropore may be important in the genesis of spina bifida.</p>\n<p><strong>Extraedge:</strong></p><p>The most characteristic event occurring during the third week of gestation is gastrulation , the process that establishes all three germ layers (ectoderm, mesoderm, and endoderm) in the Gastrulation begins with the formation of the primitive streak on the surface of the epiblast.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "From which of the following NUCLEUS PULPOSUS formed?", "options": [{"label": "A", "text": "A", "correct": true}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "A. A", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681234076-QTDA014005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A The structure marked ‘A’in image is a Notochord which forms a nucleus pulposus.</p>\n<p><strong>Highyeild:</strong></p><p>Cells of the primitive knot multiply and pass cranially to form a rod-like structure reaching up to the prochordal plate. This is the notochordal process. The notochordal process undergoes changes that convert it first into a canal and then into a plate and finally back into a rod-like structure. This is the notochord. Most of the notochord disappears. Remnants remain as the nucleus pulposus of each intervertebral disc.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B - is Paraxial mesoderm Option C - is lateral plate mesoderm Option D - is Endoderm Options B, C and D do not contribute to the formation of the Nucleus pulposus.</p>\n<p><strong>Extraedge:</strong></p><p>Intraembryonic mesoderm shows three subdivisions. The mesoderm next to the middle line is called the paraxial mesoderm. It undergoes segmentation to form somites. The mesoderm in the lateral part of the embryonic disc is called the lateral plate mesoderm. A cavity called the intraembryonic coelom appears in it and splits the mesoderm into a somatopleuric layer (in contact with ectoderm) and a splanchnopleuric layer (in contact with endoderm). A strip of mesoderm between the lateral plate mesoderm and the paraxial mesoderm is called the intermediate mesoderm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not a derivative of mesoderm?", "options": [{"label": "A", "text": "Suprarenal Medulla", "correct": true}, {"label": "B", "text": "Renal cortex", "correct": false}, {"label": "C", "text": "Cardiac muscle", "correct": false}, {"label": "D", "text": "Skeletal muscle", "correct": false}], "correct_answer": "A. Suprarenal Medulla", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Suprarenal Medulla Suprarenal medulla - Collections of sympathetic ganglions- All ganglions are Neural crest cell derivatives. The developing adrenal gland has an interesting origin. The inside core adrenal medulla is a neural crest in origin. Mesenchyme surrounding these cells differentiates to form a fetal cortex. This fetal cortex is later replaced by the adult cortex.</p>\n<p><strong>Highyeild:</strong></p><p>Important mesoderm derivatives include the muscle (smooth, cardiac, and skeletal), the muscles of the tongue (occipital somites), the pharyngeal arches muscle (muscles of mastication, muscles of facial expressions), connective tissue, the dermis and subcutaneous layer of the skin, bone and cartilage, dura mater, the endothelium of blood vessels, red blood cells, white blood cells, microglia, the dentin of teeth, the kidneys, and the adrenal cortex.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Renal cortex Option C. Cardiac muscle Option D. Skeletal muscle Options B, C and D all are mesoderm derivatives.</p>\n<p><strong>Extraedge:</strong></p><p>Either part of the adrenal gland is derived from two different embryological tissues. The adrenal cortex is derived from proliferated mesothelial cells around 5–6 weeks post-conception, while the medulla originates from the neural crest.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is mesodermal in origin?", "options": [{"label": "A", "text": "Dilator pupillae", "correct": false}, {"label": "B", "text": "Lens", "correct": false}, {"label": "C", "text": "Sphincter pupillae", "correct": false}, {"label": "D", "text": "Choroid", "correct": true}], "correct_answer": "D. Choroid", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Choroid The choroid and sclera are formed when mesenchyme proximal to the optic cup condenses into two layers, an inner vascular layer (future choroid), and an outer fibrous layer(future sclera).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Dilator pupillae Option B. Lens The lens is derived from the surface ectoderm. Option C. Sphincter pupillae Iris's muscles developed from neuroectoderm. The stroma and the anterior border layer of the iris are derived from the neural crest, and behind the stroma of the iris, the sphincter pupillae and dilator pupillae muscles, as well as the iris epithelium, develop from optic cup neuroectoderm. So both options A and C are incorrect.</p>\n<p><strong>Extraedge:</strong></p><p>The vitreous is believed to be derived partly from ectoderm and partly from mesoderm. The ectodermal component is derived mainly from the optic cup but the lens vesicle may also contribute to it. The mesodermal component comes into the optic cup through the choroidal fissure.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Diaphragm develops from all, except:", "options": [{"label": "A", "text": "Septum Transversum", "correct": false}, {"label": "B", "text": "Dorsal mesocardium", "correct": true}, {"label": "C", "text": "Pleuro-peritoneal membrane", "correct": false}, {"label": "D", "text": "Cervical myotomes", "correct": false}], "correct_answer": "B. Dorsal mesocardium", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Dorsal mesocardium EXPLANATION: Dorsal mesocardium - forms transverse sinus. The dorsal mesocardium (dorsal mesentery of the heart), formed by splanchnic mesoderm located beneath the foregut, maintains the positioning of the primitive heart tube within the pericardial cavity.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Septum Transversum The septum transversum forms the central tendon of the diaphragm. Option C. Pleuro-peritoneal membrane The pleuroperitoneal membranes develop and close the pleuroperitoneal canals. They fuse with the dorsal mesentery of the esophagus and the septum transversum. The pleuroperitoneal membranes not only form a large portion of the early fetal diaphragm but also represent only a small portion of the diaphragm in the newborn. Option D . Cervical myotomes Muscular in-growth from the body wall is contributed by cervical somites C3-C5.</p>\n<p><strong>Extraedge:</strong></p><p>At first (during the fourth week of IUL), the septum transversum lies in the cervical region opposite the third, fourth, and fifth cervical somites and is supplied by corresponding cervical spinal segments (i.e., C3, C4, and C5).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Closure of the neural tube begins at which of the following levels:", "options": [{"label": "A", "text": "Cervical Region", "correct": true}, {"label": "B", "text": "Thoracic region", "correct": false}, {"label": "C", "text": "Cephalic end", "correct": false}, {"label": "D", "text": "Caudal end", "correct": false}], "correct_answer": "A. Cervical Region", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cervical Region Neurulation - Conversion of Neural Plate to Neural Tube. Fusion begins in the cervical region and proceeds cranially and caudally. Until fusion is complete, the cephalic and caudal ends of the neural tube communicate with the amniotic cavity by cranial and caudal neuropores, respectively.</p>\n<p><strong>Highyeild:</strong></p><p>Notochord disappears but its remnants are seen in the form of nucleus pulposus of the intervertebral discs and apical ligament of dens of second cervical vertebra.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Thoracic region Option C. Cephalic end Option D. Caudal end Options B, C and D are incorrect because Fusion begins in the cervical region and proceeds cranially and caudally. Until fusion is complete, the cephalic and caudal ends of the neural tube communicate with the amniotic cavity by cranial and caudal neuropores, respectively.</p>\n<p><strong>Extraedge:</strong></p><p>Chordoma : This tumour arises from the remnants of notochord. It is formed either in the cranial region or in the sacral region. In the cranial region, it is seen at the base of the cranium and tends to spread into the nasopharynx. It commonly occurs in men later in life, over 50 years of age. About 30% of these tumours are malignant.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Failure of migration of neural crest cells is seen in:", "options": [{"label": "A", "text": "Albinism", "correct": false}, {"label": "B", "text": "Congenital megacolon", "correct": true}, {"label": "C", "text": "Odontoma", "correct": false}, {"label": "D", "text": "Adrenal tumour", "correct": false}], "correct_answer": "B. Congenital megacolon", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Congenital megacolon Congenital megacolon ( hirschsprung’s disease ) due to failure of migration of neural crest to the distal part of the GIT tube, so the absence of parasympathetic myenteric Auerbach’s ganglia. Hirschsprung disease is characterized by aganglionosis (absence of ganglion cells) in the distal colon and rectum . It is thought to either occur from a failure of neuroblasts in neural crest cells to migrate into bowel segments or degeneration of already migrated neuroblasts. It affects cells both in the myenteric and submucosal plexuses. Hence, functional obstruction develops due to a spasm in the denervated colon.</p>\n<p><strong>Highyeild:</strong></p><p>Hirschsprung is an isolated abnormality in 70% of cases, there are some well-documented a ssociations, seen in the following conditions: Down syndrome: seen in 10% of Hirschsprung cases neurocristopathy syndromes Waardenburg-Shah syndrome Haddad syndrome MEN IIa neuroblastoma other non-neurocristopathy syndromes Aarskog syndrome Bardet-Biedl syndrome Fryns syndrome Pallister-Hall syndrome Smith-Lemli-Opitz syndrome</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Albinism The term albinism usually refers to oculocutaneous albinism (OCA). OCA is a group of disorders passed down in families where the body makes little or none of a substance called melanin. Option C. Odontoma Odontomas are one of the most common mandibular lesions encountered and the most common odontogenic tumours of the mandible. They account for up to two-thirds of all such tumours; the next most common are ameloblastomas, making up the majority of the remaining one-third. Option D. Adrenal tumour An adrenal adenoma is a benign (noncancerous) tumour that forms in your adrenal glands. It's the most common type of adrenal gland tumou</p>\n<p><strong>Extraedge:</strong></p><p>The condition typically presents in term neonates with failure to pass meconium in the first 1-2 days after birth, although the later presentation is also common. Overall - 75% of cases present within six weeks of birth and over 90% of cases present within the first five years of life. In cases of delayed presentation with anorectal constipation, manometry may be useful in distinguishing short/ultrashort segment Hirschsprung disease from other causes. A definitive diagnosis requires a full-thickness rectal biopsy (2 cm above the dentate line as the region below the dentate line usually is aganglionic).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All of the following are the derivatives of the neural crest cells except:", "options": [{"label": "A", "text": "Melanocyte", "correct": false}, {"label": "B", "text": "Adrenal medulla", "correct": false}, {"label": "C", "text": "Sympathetic ganglia", "correct": false}, {"label": "D", "text": "Cauda equina", "correct": true}], "correct_answer": "D. Cauda equina", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cauda equina Cauda equina is developed from the neural tube</p>\n<p><strong>Highyeild:</strong></p><p>Neural Crest Derivatives ● Connective tissue and bones of the face and skull ● Cranial nerve ganglia ● C cells of the thyroid gland ● Conotruncal septum in the heart ● Odontoblasts ● Dermis in the face and neck ● Spinal (dorsal root ganglia ● Sympathetic chain and preaortic ganglia ● Parasympathetic ganglia of the ● gastrointestinal tract Adrenal medulla ● Schwann cells ● Glial cells ● Meninges (forebrain] ● Melanocytes ● Smooth muscle cells to blood vessels of the face and forebrain</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option A. Melanocyte Option B. Adrenal medulla Option C . Sympathetic ganglia Options A, B and C all are derivatives of the neural crest.</p>\n<p><strong>Extraedge:</strong></p><p>The proximal part of the notochordal canal persists temporarily as a neurenteric canal and forms a transitory communication between the amniotic cavity and the yolk sac (umbilical vesicle).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 5-day-old male infant is diagnosed with Hirschsprung disease. CT scan examination reveals an abnormally dilated colon. Which of the following is the most likely embryological mechanism responsible for Hirschsprung disease?", "options": [{"label": "A", "text": "Failure of neural crest cells to migrate into the walls of the colon", "correct": true}, {"label": "B", "text": "Incomplete separation of the cloaca", "correct": false}, {"label": "C", "text": "Failure of recanalization of the colon", "correct": false}, {"label": "D", "text": "Defective rotation of the hindgut", "correct": false}], "correct_answer": "A. Failure of neural crest cells to migrate into the walls of the colon", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Failure of neural crest cells to migrate into the walls of the colon Congenital megacolon (Hirschsprung disease) results from the failure of neural crest cells to migrate into the walls of the colon. Oligohydramnios is a deficiency of amniotic fluid, which can cause pulmonary hypoplasia but would not cause Hirschsprung disease.</p>\n<p><strong>Highyeild:</strong></p><p>Hirschsprung disease is caused by mutations in the RETgene, which codes for a cell membrane tyrosine kinase receptor. This gene on chromosome 10q11 is essential for neural crest cell migration.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option B. Incomplete separation of the cloaca Incomplete separation of the cloaca would result in anal agenesis either with or without the presence of a fistula. Option C. Failure of recanalization of the colon The failure of recanalization of the colon results in rectal atresia, wherein both the anal canal and rectum exist but are not connected due to incomplete canalization or no recanalization. Option D. Defective rotation of the hindgut Defective rotation of the hindgut can cause volvulus or twisting of its contents.</p>\n<p><strong>Extraedge:</strong></p><p>Pheochromocytomas are rare tumours involving chromaffin cells that result in excessive production and release of epinephrine and norepinephrine causing paroxysmal episodes of hypertension, increased heart rate, headaches, and other associated symptoms. Most occur in the adrenal medulla, but approximately 10% occur in other sites, usually the abdomen. Twenty-five per cent are familial and have been associated with mutations in the RETgene that plays a role in neural crest cell migration.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 22 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 54-year-old female marathon runner presents with pain in her right wrist that resulted when she fell with force on her outstretched hand. Radiographic studies indicate an anterior dislocation of a carpal bone (See Image). Which of the following bones is most likely dislocated?", "options": [{"label": "A", "text": "Capitate", "correct": false}, {"label": "B", "text": "Lunate", "correct": true}, {"label": "C", "text": "Scaphoid", "correct": false}, {"label": "D", "text": "Trapezoid", "correct": false}], "correct_answer": "B. Lunate", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683683903267-QTDA107001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lunate The lunate is the most commonly dislocated carpal bone because of its shape and relatively weak ligaments anteriorly.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Capitate - The Capitate bone is located in the distal row of the carpal bones. Option: C . Scaphoid - Dislocations of the scaphoid and triquetrum are relatively rare. Option: D. Trapezoid - The trapezoid bone is located in the distal row of the carpal bones. Proximal and Distal Row of Carpal bones</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 55-year-old female is being treated in the emergency department after she fell from the stage into the orchestra set. Radiographs revealed a fracture of the styloid process of the ulna. Disruption of the triangular fibrocartilage (TFCC) complex is suspected. With which of the following bones does the ulna normally articulate at the wrist?", "options": [{"label": "A", "text": "Triquetrum", "correct": false}, {"label": "B", "text": "Hamate", "correct": false}, {"label": "C", "text": "Radius and lunate", "correct": false}, {"label": "D", "text": "Radius", "correct": true}], "correct_answer": "D. Radius", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Radius Normally, the distal part of the ulna articulates only with the radius bone at the distal radioulnar joint at the wrist, a joint that participates in pronation/ supination. Distal Radio-ulanar Articulation</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Options A, B, and C are incorrect options because: The head of the ulna does not articulate with any of the carpal bones; instead, it is separated from the triquetrum and lunate bones by the triangular fibrocartilage complex between it and the radius. The pisiform articulates with the triquetrum. The carpal articulation of the radius is primarily that of the scaphoid bone.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Contents of mid-palmar space are all, except:", "options": [{"label": "A", "text": "2nd Lumbrical", "correct": false}, {"label": "B", "text": "FDP of 3rd finger", "correct": false}, {"label": "C", "text": "1st lumbrical", "correct": true}, {"label": "D", "text": "FDP of 4th finger", "correct": false}], "correct_answer": "C. 1st lumbrical", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1st lumbrical The first lumbrical muscle is related to the mid-palmar space.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Infections of the index finger spread to:", "options": [{"label": "A", "text": "Mid Palmar Space", "correct": false}, {"label": "B", "text": "Radial bursa", "correct": false}, {"label": "C", "text": "Thenar space", "correct": true}, {"label": "D", "text": "Dorsum of hand", "correct": false}], "correct_answer": "C. Thenar space", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thenar space Infection of the thumb and index finger spread to thenar space.</p>\n<p><strong>Highyeild:</strong></p><p>Infection of thenar space: Infection of the thumb may also spread to the radial bursa. Thus, the infection may reach the thenar space from this infected radial bursa or from the synovial sheath of the index finger. Infection of mid-palmar space : Infection of the Ulnar bursa is usually secondary to the infection of the middle, ring, and little finger, and this, in turn, may spread to the forearm space of the Parona. Thus it is considered as the inlet and lumbrical canals as the outlets for infection of the mid-palmar space.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Mid Palmar Space Infection of the middle, ring, and little finger spread to mid-palmar space. Infection of mid-palmar space : Infection of the Ulnar bursa is usually secondary to the infection of the middle, ring, and little finger, and this, in turn, may spread to the forearm space of the Parona. Thus it is considered as the inlet and lumbrical canals as the outlets for infection of the mid-palmar space. Option: B. Radial bursa Infection may reach the thenar space from the infected radial bursa or from the synovial sheath of the index finger, secondarily. Digital Synovial Sheaths The synovial sheaths of the 2nd, 3rd, and 4th digits are independent and terminate proximally at the levels of the heads of the metacarpals. The synovial sheath of the little finger is continuous proximally with the ulnar bursa and that of the thumb with the radial bursa. Therefore, infections of the little finger and thumb are more dangerous because they can spread into the palm and even up to 2.5 cm above the wrist. Option: D. Dorsum of hand Infections of the index finger do not communicate with the dorsum of the hand. Mid-Palmar and Thenar Space of hand</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True statement about deep palmar arch:", "options": [{"label": "A", "text": "Main contribution is the ulnar artery.", "correct": false}, {"label": "B", "text": "Lie superficial to lumbricals", "correct": false}, {"label": "C", "text": "Gives three perforating branches", "correct": true}, {"label": "D", "text": "Gives four palmar metacarpal arteries.", "correct": false}], "correct_answer": "C. Gives three perforating branches", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Gives three perforating branches The deep Palmar arch gives three perforating and three palmar metacarpal arteries. So option C is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Difference between Deep and Superficial palmar arch Superficial palmar arch Deep palmar arch Formation By anastomosis between direct continuation of the ulnar artery (i.e., superficial palmar branch) with the small superficial branch of the radial artery By anastomosis between direct continuation of the radial artery with the small deep palmar branch of the ulnar artery Location Superficial to long flexor tendons Deep to long flexor tendons Branches ● Three common palmar digital arteries● One proper digital artery● Cutaneous branches ● Three palmar metacarpal arteries● Three perforating arteries● Recurrent branches</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Main contribution is the ulnar artery. The deep palmar arch is formed by anastomosis of the end of the radial artery with the deep palmar branch of the ulnar artery. Option: B. Lie superficial to lumbricals The deep palmar arch lies deep to lumbricals Option: D. Gives four palmar metacarpal arteries. The deep Palmar arch gives three perforating and three palmar metacarpal arteries. Deep Palmar Arch</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The roof of the anatomical snuff box is formed by:", "options": [{"label": "A", "text": "Cephalic vein and superficial branch of radial nerve", "correct": true}, {"label": "B", "text": "Basilic vein and superficial branch of radial nerve", "correct": false}, {"label": "C", "text": "Radial artery and superficial branch of radial nerve", "correct": false}, {"label": "D", "text": "Basilic vein only", "correct": false}], "correct_answer": "A. Cephalic vein and superficial branch of radial nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cephalic vein and superficial branch of radial nerve The roof of the anatomical snuff box contains a cephalic vein and a superficial branch of the radial nerve.</p>\n<p><strong>Highyeild:</strong></p><p>Boundaries of anatomical snuff box: Posteromedially(ulnar border)-extensor Pollicis longus Anterolaterally (radial border)-extensor pollicis brevis and abductor pollicis longus. The floor of the anatomical snuff box: is formed by Scaphoid, Trapezium, Base of 1st metacarpal, and styloid process of the radius. Radial artery content of Anatomical snuff box</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Basilic vein and superficial branch of radial nerve The basilic vein is not contained in the roof of the anatomical snuff box. Option: C. Radial artery and superficial branch of radial nerve The radial artery is contained in the anatomical snuff box. The pulse of the radial artery is palpable on the floor of the snuffbox against the scaphoid bone. Option: D. Basilic vein only The basilic vein is not contained in the roof of the anatomical snuff box.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Diminished sweating and increased warmth and vasodilation of the skin vessels over the hypothenar eminence as well as the ring and the little fingers could result from the following except which?", "options": [{"label": "A", "text": "A lesion of the posterior cord of the brachial plexus", "correct": true}, {"label": "B", "text": "Ulnar nerve damage behind the medial epicondyle of the humerus", "correct": false}, {"label": "C", "text": "A lesion of the medial cord of the brachial plexus", "correct": false}, {"label": "D", "text": "A lesion of the eighth cervical nerve", "correct": false}], "correct_answer": "A. A lesion of the posterior cord of the brachial plexus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A lesion of the posterior cord of the brachial plexus Lesion of posterior cord of brachial plexus mainly involves injury of radial and axillary nerve and the patient presents with wrist drop.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B, C and D are correct statements about clinical features mentioned in the question. The sweat glands and the blood vessels of the skin over the hypothenar eminence and the palmar surface of the medial one and a half fingers are innervated by sympathetic postganglionic nerve fibers. These fibers travel in the eighth cervical and first thoracic spinal nerves, the medial cord of the brachial plexus, and the ulnar nerve and its palmar cutaneous and digital branches.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which among the following is characteristic of damage to the corticospinal (pyramidal) system?", "options": [{"label": "A", "text": "Babinski’S Sign", "correct": true}, {"label": "B", "text": "Flaccid paralysis and hypotonia", "correct": false}, {"label": "C", "text": "Immediate muscle degeneration and atrophy", "correct": false}, {"label": "D", "text": "Intention tremor", "correct": false}], "correct_answer": "A. Babinski’S Sign", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Babinski’S Sign The Babinski sign—dorsiflexion of the great toe in response to stroking the plantar aspect of the foot—is a characteristic sign of pyramidal tract involvement. Signs and symptoms of corticospinal tract injury that are nearly always apparent to some degree include spastic paralysis, hypertonia, loss of deep tendon reflexes, and hyperactive abdominal and cremasteric reflexes.</p>\n<p><strong>Highyeild:</strong></p><p>Comparison of pyramidal and extrapyramidal tracts Pyramidal tracts Extrapyramidal tracts Recent in evolution Older in evolution These comprise only cortico- spinal and corticonuclear tracts These comprise olivospinal, vestibulospinal, tectospinal, reticulospinal, rubrospinal tracts Origin from motor cortex These arise from olivary vesti- bular, tectum (collicular), reticular and red nuclei The impulse passes directly to anterior horn cells Impulse passes by polysynaptic route via cortex, basal ganglia, cerebellum and brainstem Function is to perform voluntary skilled movement Control tone and equilibrium. These facilitate/inhibit flexor/ extensor reflexes Injury leads to increased muscle tone and loss of motor activity Injury leads to increased muscle tone with clasp knife rigidity</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B . Flaccid paralysis and hypotonia are commonly seen following lower motor neuron injury, as is loss of deep tendon reflexes). Option: C. Muscle degeneration and atrophy are not characteristic symptoms of corticospinal tract damage. Option: D. The presence of an intentional tremor is a sign of cerebellar damage and is not seen with corticospinal tract lesions.</p>\n<p><strong>Extraedge:</strong></p><p>The descending tracts Name Function Crossed and uncrossed Beginning Termination Pyramidal tracts 1.Lateral corticospinal 2.Anterior corticospinal Main motor tract for skillful voluntary movements Facilitates flexors Crosses in medulla Crosses in corresponding spinal segment Motor area of cortex (areas 4, 6) Motor area of cortex (areas 4, 6) Anterior grey column cells (alpha motor neurons) Anterior grey column cells (alpha motor neurons) Extrapyramidal tracts 1. Rubrospinal Efferent pathway for cere- bellum and corpus striatum Crossed Red nucleus of midbrain Alpha and gamma motor neurons of anterior grey column cells 2. Medial reticulospinal Extrapyramidal tract Facilitates extensors Uncrossed Reticular formation of grey matter of pons Alpha and gamma motor neurons of anterior grey column cells 3. Lateral reticulospinal Extrapyramidal tract Facilitates flexors Uncrossed and crossed Reticular formation of grey matter of medulla oblongata Alpha and gamma motor neurons of anterior grey column cells 4. Olivospinal Extrapyramidal tract Uncrossed Inferior olivary nucleus Alpha and gamma motor neurons of anterior grey column cells 5. Lateral vestibulospinal Efferent pathway for equilibratory control Uncrossed Lateral vestibular nucleus Alpha and gamma motor neurons of anterior grey column cells 6. Tectospinal Efferent pathway for visual reflexes Crossed Superior colliculus Alpha and gamma motor neurons of anterior grey column cells 7. Descending auto- nomic fibres Control parasympathetic and sympathetic systems Cerebral cortex hypothalamus reticular formation Parasympathetic and sympathetic out flows</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The efferent limb of the pupillary light reflex is interrupted along with corticospinal and corticobulbar fibers in which of the following clinical entities?", "options": [{"label": "A", "text": "Broca’S Aphasia", "correct": false}, {"label": "B", "text": "Inferior alternating hemiplegia", "correct": false}, {"label": "C", "text": "Middle alternating hemiplegia", "correct": false}, {"label": "D", "text": "Superior alternating hemiplegia", "correct": true}], "correct_answer": "D. Superior alternating hemiplegia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Superior alternating hemiplegia Compression of cranial nerve III, in combination with descending corticospinal and corticobulbar fibers, occurs as part of superior alternating hemiplegia. Superior alternating hemiplegia</p>\n<p><strong>Highyeild:</strong></p><p>Superior alternating hemiplegia (also known as Weber syndrome) has a few distinct symptoms: contralateral hemiparesis of limb and facial muscle accompanied by weakness in one or more muscles that control eye movement on the same side. Another symptom is the loss of eye movement due to damage to the oculomotor nerve fibers. The upper and lower extremities have increased weakness.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Patients with Broca’s aphasia typically do not exhibit involvement of the pupillary light reflexes. Option: B, C. Inferior alternating hemiplegia and middle alternating hemiplegia involve cranial nerves XII and VI, respectively, in combination with corticospinal fibers. Wallenberg syndrome (lateral medullary syndrome) typically does not include damage to the corticospinal tract. Middle alternating hemiplegia</p>\n<p><strong>Extraedge:</strong></p><p>Middle alternating hemiplegia (also known as Foville Syndrome) typically constitutes weakness of the extremities accompanied by paralysis of the extraocular muscle, specifically lateral rectus, on the opposite side of the affected extremities, which indicates a lesion in the caudal and medial pons involving the abducens nerve root (controls movement of the eye) and corticospinal fibers (carries motor commands from the brain to the spinal cord). Inferior alternating hemiplegia Inferior alternating hemiplegia (also known as a medial medullary syndrome) typically involves a \"weakness of the extremities accompanied by paralysis of muscles on the ipsilateral side of the tongue (seen as a deviation of the tongue on that side on protrusion). These symptoms indicate a lesion in the medulla involving the corticospinal fibers in the pyramid and the exiting hypoglossal nerve roots.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 70-year-old male known case of prostate cancer presented to our emergency department with a one-week history of bilateral lower extremity weakness, urinary retention, and bowel incontinence, which worsened one day. The patient was subjected to various investigations and was diagnosed with a case of conus medullaris syndrome due to metastasis of cancer. What findings are expected in an MRI of the spinal cord?", "options": [{"label": "A", "text": "A destructive lesion and a burst fracture of the S2, S3, and S4 vertebral body with severe spinal canal stenosis", "correct": true}, {"label": "B", "text": "S2, S3, S4 vertebral body with severe spinal canal stenosis and normal vertebral body", "correct": false}, {"label": "C", "text": "A destructive lesion and a burst fracture of the L1, L2, L3 vertebral body with severe spinal canal stenosis", "correct": false}, {"label": "D", "text": "Complete transection of the sacral part of spinal cord", "correct": false}], "correct_answer": "A. A destructive lesion and a burst fracture of the S2, S3, and S4 vertebral body with severe spinal canal stenosis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A destructive lesion and a burst fracture of the S2, S3, and S4 vertebral body with severe spinal canal stenosis Brusr fracture of S2, S3, S4 carry a sacral component of the parasympathetic system to bowel and bladder Due to injury of these components, there is urinary retention and bowel dysfunction. There is also sexual dysfunction There is a sensory loss in the perineum.</p>\n<p><strong>Highyeild:</strong></p><p>Conus medullaris syndrome is a collection of signs and symptoms associated with injury to the conus medullaris. It typically causes back pain and bowel and bladder dysfunction, spastic or flaccid weakness depending on the level of the lesion, and bilateral sensory loss. Comparatively, cauda equina syndrome may cause radicular pain, bowel/bladder dysfunction, patchy sensory loss or saddle anesthesia, and lower extremity weakness at the lumbar and sacral roots level.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. S2, S3, S4 vertebral body with severe spinal canal stenosis and normal vertebral body As this is a case of conus medullaris syndrome due to metastasis of prostate cancer, mostly metastatic tumors produce destructive lesions. This destructive lesion results in fracture of sacral vertebral bodies. Option: C. A destructive lesion and a burst fracture of the L1, L2, and L3 vertebral body with severe spinal canal stenosis Stenosis of the lumbar region is mainly due to a degenerative process after the age of 60. Symptoms are: Numbness or tingling in a foot or leg Weakness in a foot or leg Pain or cramping in one or both legs when you stand for long periods of time or when you walk, which usually eases when you bend forward or sit Back pain As this symptoms are not found in given case less like to be lumbar spinal stenosis Option: D. Complete transection of sacral part of spinal cord Transection of spinal cord mainly seen during sudden traumatic events. Non traumatic transactions are rare, and can be due to inflammation, arthritis, cancer, disc degeneration etc. As this patient has no history of trauma. So it is less likely to be a cause of complete transection of the spinal cord.</p>\n<p><strong>Extraedge:</strong></p><p>The conus medullaris or conus terminalis is the tapered, lower end of the spinal cord. It occurs near lumbar vertebral levels 1 (L1) and 2 (L2), occasionally lower.The upper end of the conus medullaris is usually not well defined, however, its corresponding spinal cord segments are usually S1-S5</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 28-year-old man presented to the emergency department for low back pain and numbness in both lower extremities. Two days earlier, he had sharp, shooting pains in the back and buttocks after moving boxes. On the morning of presentation, the patient awoke with numbness in both lower extremities and had left leg weakness so severe that the patient was unable to stand or walk without support. The patient described the pain as mild while he was supine and worse when he sat or stood. He did have morning erections. There was no bowel and bladder dysfunction. The patient reported that he had had an industrial injury five years before that resulted in a herniated lumbar disc at level of L2,L3, L4,L5. What is the most probable diagnosis?", "options": [{"label": "A", "text": "Cauda Equina Syndrome", "correct": true}, {"label": "B", "text": "Conus medullaris syndrome", "correct": false}, {"label": "C", "text": "Sciatic nerve compression", "correct": false}, {"label": "D", "text": "Peripheral vascular disease", "correct": false}], "correct_answer": "A. Cauda Equina Syndrome", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Cauda Equina Syndrome Cauda equina is formed by dorsal and ventral nerve roots of L1 to L5 and S1 to S5 and Co1 lying vertically to the filum terminale. Damage to this cauda equina, as here L2, L3, L4, L5, results : Lower motor neuron type of paralysis in lower limb Root pain Bladder and bowel involvement in the latter stages.</p>\n<p><strong>Highyeild:</strong></p><p>Cauda equina syndrome Cauda equina syndrome is caused by a compression or irritation of lumbosacral spinal nerve roots, often due to lumbar disc herniation. The most common symptoms include low back pain that radiates into the sacral region and legs, and bilateral motor and sensory deficits, which present as asymmetric saddle anesthesia (S2-S5 dermatomes) and asymmetric lower limb weakness. Additional clinical features may include loss of bladder control (urinary retention), fecal incontinence, and erectile dysfunction, which are often late findings and less frequent.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Conus medullaris syndrome In the case of Conus medullaris syndrome lower motor type of paralysis of the lower limb is not seen. Due to injury of S2, S3, and S4 components, there is Urinary retention and bowel dysfunction. There is also sexual dysfunction There is a sensory loss in the perineum Option: C. Sciatic nerve pain Sciatic nerve pain is root pain. It radiates to the back and increases in severity while walking It rarely causes lower motor neuron paralysis Option: D. Peripheral vascular disease For peripheral vascular disease there must be a history of presence of comorbidities or family history of vasculitis. In peripheral vascular disease, the pain increases while doing the There is no presence of rot pain in peripheral vascular disease.</p>\n<p><strong>Extraedge:</strong></p><p>Conus medullaris syndrome Conus medullaris syndrome, although quite similar, is clinically distinct from cauda equina syndrome. This syndrome is much less common and is typically caused by tumors or vascular anomalies within the spinal canal. It is characterized by symmetric saddle anesthesia and symmetric weakness in the lower extremities, with associated bladder dysfunction and early bowel incontinence.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In which of the following infectious diseases given below is there involvement of the spinal root?", "options": [{"label": "A", "text": "Herpes Zoster", "correct": false}, {"label": "B", "text": "Poliomyelitis", "correct": false}, {"label": "C", "text": "Syphilis", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above Option: A. Herpes zoster, or shingles, is the painful eruption of a rash, usually unilateral, caused by the varicella-zoster Varicella zoster virus usually persists asymptomatically in the dorsal root ganglia of anyone who has had chickenpox, reactivating from its dormant state in about 25% of people to travel along the sensory nerve fibers and cause vesicular lesions in the dermatome supplied by that nerve. Option: B. Poliomyelitis is a viral disease involving anterior horn cells causing the flaccid paralysis of the lower limb. Sometimes it involves cervical segment resulting in death due to paralysis of diaphragm. Option: C. In the tertiary stage of syphilis there is degenerative lesion of dorsal nerve roots and posterior white column, resulting in severe pain in lower limbs. Therefore Option D all of the above is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Poliomyelitis : It is a viral disease which involves anterior horn cells leading to flaccid paralysis of the affected segments. It is a lower motor neuron paralysis. If poliomyelitis affects the upper cervical segments of spinal cord, it may be fatal because of the involvement of C4 segment which supplies the diaphragm through phrenic nerve.</p>\n<p><strong>Extraedge:</strong></p><p>Level of vertebral levels and spinal segments Vertebral levels Spinal segments C1-C7 C1–C8 T1-T6 T1-T8 T7-T9 T9-T12 T10-T11 L1-L5 T12-L1 S1-S5 and Co1</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 28-year-old man is brought to the emergency department after he sustained a stab wound to his back. He reports weakness and numbness of the lower extremities. He had no history of serious illness. On arrival, he is alert and cooperative. examination shows a deep 4-cm laceration on his back next to the vertebral column at the level of the T10 vertebra. Neurologic examination shows right-sided flaccid paralysis with a diminished vibratory sense ipsilaterally, decreased sensation to light touch at the level of his laceration and below, and left-sided loss of hot, cold, and pin-prick sensation at the level of the umbilicus and below. Which tract of the spinal cord is most likely to be affected?", "options": [{"label": "A", "text": "Right lateral corticospinal tract and right dorsal column", "correct": true}, {"label": "B", "text": "Left lateral corticospinal tract and left dorsal column", "correct": false}, {"label": "C", "text": "Right lateral corticospinal tract and left dorsal column", "correct": false}, {"label": "D", "text": "Left lateral corticospinal tract and right dorsal column", "correct": false}], "correct_answer": "A. Right lateral corticospinal tract and right dorsal column", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right lateral corticospinal tract and right dorsal column The lateral corticospinal tract contains over 90% of the fibers present in the corticospinal tract and runs the length of the spinal cord. The primary function of the lateral corticospinal tract is to control the voluntary movement of contralateral limbs. Due to the pyramidal decussation of the lateral corticospinal tract in the caudal medulla, damage rostral or caudal to this decussation will be the defining feature of whether there will be ipsilateral or contralateral deficits. For example: If there is a lesion in the precentral gyrus of the left cerebral cortex, the patient will exhibit upper motor neuron signs with damage to the right side of the body. Contrarily, if spinal cord damage is on the left side (below the pyramidal decussation), motor deficits will be present on the left side of the body. If there is spinal cord damage at the level of the anterior horn, then lower motor neuron signs will be present with ipsilateral deficits. The dorsal column-medial lemniscus pathway is a sensory pathway of the central nervous system that conveys sensations of fine touch, vibration, two-point discrimination, and proprioception (position) from the skin and joints. The pathway receives information from sensory receptors throughout the body and carries this in nerve tracts in the white matter of the dorsal columns of the spinal cord to the medulla, where it is continued in the medial lemniscus, onto the thalamus and relayed from there through the internal capsule and transmitted to the somatosensory cortex.</p>\n<p><strong>Highyeild:</strong></p><p>Brown-Séquard syndrome may be caused by injury to the spinal cord resulting from a spinal cord tumor, trauma [such as a fall or injury from gunshot or puncture to the cervical or thoracic spine], ischemia (obstruction of a blood vessel), or infectious or inflammatory diseases such as tuberculosis, or multiple sclerosis. As a result of the injury to these three main brain pathways the patient will present with three lesions: The corticospinal lesion produces spastic paralysis on the same side of the body below the level of the lesion (due to loss of moderation by the UMN). At the level of the lesion, there will be flaccid paralysis of the muscles supplied by the nerve of that level (since lower motor neurons are affected at the level of the lesion). The lesion to fasciculus gracilis or fasciculus cuneatus (dorsal column) results in ipsilateral loss of vibration and proprioception (position sense) and loss of all sensation of fine touch. The loss of the spinothalamic tract leads to pain and temperature sensation being lost from the contralateral side, beginning one or two segments below the lesion.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Left lateral corticospinal tract and left dorsal column Option: C. Right lateral corticospinal tract and left dorsal column Option: D. Left lateral corticospinal tract and right dorsal column Option B, C, and D are incorrect answers because the patient present with right-sided flaccid paralysis with a diminished vibratory sense ipsilaterally, decreased sensation to light touch at the level of his laceration so, Right lateral corticospinal tract and right dorsal column will be involved.</p>\n<p><strong>Extraedge:</strong></p><p>Brown-Séquard syndrome is caused by damage to one half of the spinal cord, i.e., hemisection of the spinal cord resulting in paralysis and loss of proprioception on the same (or ipsilateral) side as the injury or lesion, and loss of pain and temperature sensation on the opposite (or contralateral) side as the lesion. In addition, if the lesion occurs above T1 of the spinal cord, it will produce ipsilateral Horner's syndrome with the involvement of the oculosympathetic pathway.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 35-year-old woman comes to OPD for treatment of burns on her left hand. On examination, numerous healed scars are seen on the hand. She complains of a decrease in hot and cold sensations in her right and left hand in comparison to her lower limbs. On follow-up after 1 month, she complained of increased weakness in her upper limbs. On MRI, tubular cavitation of the spinal cord is seen. What is the most likely diagnosis?", "options": [{"label": "A", "text": "Cervical Disc Prolapse", "correct": false}, {"label": "B", "text": "Syringomyelia", "correct": true}, {"label": "C", "text": "Multiple sclerosis", "correct": false}, {"label": "D", "text": "Amyotrophic lateral sclerosis", "correct": false}], "correct_answer": "B. Syringomyelia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Syringomyelia Syringomyelia is a condition in which an abnormal fluid-filled cavity, or syrinx, develops within the central canal of the spinal cord. The syrinx is a result of disrupted CSF drainage from the central canal, commonly caused by a Chiari malformation or previous trauma to the cervical or thoracic spine. The syrinx initially compresses and permanently damages crossing fibers of the spinothalamic tract. often asymptomatic characterized by and slowly progressing (similar to central cord syndrome) Cape-like distribution (neck, shoulders, arms) Dissociated sensory loss Dysesthetic pain Muscle atrophy, fasciculations, and areflexia (patients may present with a claw hand deformity)</p>\n<p><strong>Highyeild:</strong></p><p>Comparison between lower motor neuron (LMN) and upper motor neuron (UMN) paralyzes LMN paralysis UMN paralysis Muscle tone abolished Muscle tone increased Leads to flaccid paralysis Leads to spastic paralysis Muscles atrophy later No atrophy of muscles Reaction of degeneration seen Reaction of degeneration not seen Tendon reflexes absent Limited damage Ipsilateral Tendon reflexes exaggerated Extensive damage Mostly contralateral Babinski sign negative Babinski sign positive All superficial and deep reflexes lost due to damage to motor pathways Superficial reflexes, like abdominal, cremasteric, plantar, are lost due to damage to corticospinal tracts May affect single muscle group as in poliomyelitis and Bell's palsy Affects many groups of muscles as in hemiplegia. Damage to corticospinal tract removes the inhibitory effect on the super- ficial reflexes, resulting in Babinski positive sign There is loss of control on lower motor neurons, which become hyperactive, leading to spastic paralysis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Cervical disc prolapse Cervical disc prolapse is due to degeneration of the cervical disc resulting in spinal cord stenosis. Cervical disc prolapse has radicular symptoms that are more prominent than sensory impairment. Option: C. Multiple sclerosis All symptoms of multiple sclerosis similar to syringomyelia except muscle atrophy which is uncommon. Option: D. Amyotrophic lateral sclerosis All symptoms of multiple sclerosis are similar to syringomyelia except sensory loss, which is uncommon.</p>\n<p><strong>Extraedge:</strong></p><p>Amyotrophic lateral sclerosis : It is a degenerative disease that is caused due damage to of the cells in the ventral horn. The clinical features involve weakness, atrophy of muscles of hands and arms, and later extending to the lower limb.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Romberg’s sign is used to determine the integrity of which pathway?", "options": [{"label": "A", "text": "Corticospinal Pathway", "correct": false}, {"label": "B", "text": "Cerebellovestibular pathway", "correct": false}, {"label": "C", "text": "Dorsal column pathway", "correct": true}, {"label": "D", "text": "Cortico Cerebellar Pathway", "correct": false}], "correct_answer": "C. Dorsal column pathway", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Dorsal column pathway The dorsal column is a three-order neuronal pathway that functions as a method of signal transmission throughout the spinal cord to the brainstem. This pathway specifically controls conscious appreciation of vibration, fine touch, 2-point discrimination, and proprioception. Specifically, in cases of neurosyphilis, or tabes dorsalis, there is demyelination of the axonal fibers of the posterior column or dorsal pathway of the spinal cord. This demyelination leads to severe sensory deficits of the pathway, including position sense or proprioception. Due to its high specificity, a positive Romberg sign is highly suggestive of diagnosing a deficit involving the dorsal column and medial lemniscus</p>\n<p><strong>Highyeild:</strong></p><p>Romberg's test, Romberg's sign, or the Romberg maneuver, is a test used in an exam of neurological function for balance. The exam is based on the premise that a person requires at least two of the three following senses to maintain balance while standing: proprioception (the ability to know one's body position in space); vestibular function (the ability to know one's head position in space); and vision (which can be used to monitor and adjust for changes in body position). The Romberg test is a test of the body's sense of positioning (proprioception), which requires healthy functioning of the dorsal columns of the spinal cord.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Corticospinal Pathway Due to its high specificity, a positive Romberg sign is highly suggestive of diagnosing a deficit involving the dorsal column and medial lemniscus pathways, therefore Option A is incorrect answer. Option: B. Cerebellovestibular pathway Option: D. Cortico Cerebellar Pathway Although the cerebellum is also involved with coordination, Romberg's test detects the integrity of the posterior dorsal columns and proprioception, the body's awareness of its own movement and position in space. It is important to understand that a negative romberg test does not confirm cerebellar dysfunction, therefore both option B and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Romberg sign and cerebellar function Romberg's test is not a test of cerebellar function, as it is commonly misconstrued. Patients with severe cerebellar ataxia will generally be unable to balance even with their eyes open;therefore, the test cannot proceed beyond the first step and no patient with cerebellar ataxia can correctly be described as Romberg's positive. Rather, Romberg's test is a test of the proprioception receptors and pathways function. A positive Romberg's test which will show wide base gait in patients with back pain has been shown to be 90 percent specific for lumbar spinal stenosis.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Herniation of the intervertebral disc between the 4th and 5th lumbar vertebrae most likely impinges on the roots of which spinal nerve?", "options": [{"label": "A", "text": "L3", "correct": false}, {"label": "B", "text": "L4", "correct": false}, {"label": "C", "text": "L5", "correct": true}, {"label": "D", "text": "S1", "correct": false}], "correct_answer": "C. L5", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>L5 A bulging or protruded disc typically affects the traversing nerve root; that is, the nerve affected is one number greater than the number of the disc. Herniation of the intervertebral disc between the 4th and 5th lumbar vertebrae most likely impinges on the roots of L5 spinal nerves.</p>\n<p><strong>Highyeild:</strong></p><p>Level of vertebral levels and spinal segments Vertebral levels Spinal segments C1-C7 C1–C8 T1-T6 T1-T8 T7-T9 T9-T12 T10-T11 L1-L5 T12-L1 S1-S5 and Co1</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The L3 spinal nerve would be affected by the protrusion of the L2 Option: B. intervertebral disk. The L4 spinal nerve would be affected by the protrusion of the L3 intervertebral disc. Option: D. The S1 spinal nerve would be affected by the L5 intervertebral disk protrusion. The S2 spinal nerve exits through the foramina of the fused sacrum and, therefore, is not subject to compression by herniated intervertebral disks</p>\n<p><strong>Extraedge:</strong></p><p>Classification of Nerve Fibers by Speed of Conduction and Size Fiber Type Conduction Velocity (m/s) Fiber Diameter (um) Functions Myelin Sensitivity to Local Anesthetics A Fibers α 70-120 12-20 Motor, skeletal muscle Yes Least β 40-70 5-12 Sensory, touch, pressure, vibration Yes γ 10-50 3-6 Muscle spindle Yes 8 6-30 2-5 Pain (sharp, localized), temperature, touch Yes B Fibers 3-15 ≤3 Preganglionic autonomic Yes C Fibers 0.5-2.0 0.4-1.2 Pain (diffuse, deep), temperature, postganglionic autonomic No Most</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Intervertebral discs may protrude or rupture in any direction, but they most commonly protrude in which direction?", "options": [{"label": "A", "text": "Anteriorly", "correct": false}, {"label": "B", "text": "Anterolaterally", "correct": false}, {"label": "C", "text": "Laterally", "correct": false}, {"label": "D", "text": "Posterolaterally", "correct": true}], "correct_answer": "D. Posterolaterally", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterolaterally Intervertebral discs may protrude or rupture in any direction but do so most commonly in a posterolateral direction, just lateral to the strong central portion of the posterior longitudinal ligament. This is usually the weakest part of the disc, because the annulus is thinner here and is not supported by other ligaments.</p>\n<p><strong>Highyeild:</strong></p><p>Multiple Sclerosis Multiple sclerosis is a common disease confined to the CNS, causing demyelination of the ascending and descend- ing tracts. It is a disease of young adults, and the cause is unknown. Autoimmunity, Infection, and heredity, alone or in combination, may play a role In Its etiology. A breach In the Integrity of the blood-brain barrier In an Individual who is genetically predisposed to the disease may be This could result in the invasion of the brain and spinal cord by some Infection allowing leukocytes to enter the normally immunologically protected CNS.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Anteriorly the intervertebral disks are supported by the broad and strong anterior ligament. Herniation is less common in this direction. Option: B. Anterolaterally, the intervertebral disk is supported by the broad anterior longitudinal ligament. The nucleus pulposus is also situated posteriorly in the disk, making herniation here less likely. Option: C. Herniation of the intervertebral disk laterally is not particularly common. Posteriorly the intervertebral disks are supported by the posterior longitudinal ligament. Herniation is less common in this direction.</p>\n<p><strong>Extraedge:</strong></p><p>Comparison of Structural Details in Different Regions of the Spinal Cord Region Shape White Matter Gray Matter Anterior Gray Column Posterior Gray Column Lateral Gray Column Cervical Oval Fasciculus cuneatus and fasciculus gracilis present Medial group of cells for neck muscles; central group of cells for accessory nucleus (C1-C5) and phrenic nucleus (C3-C5); lateral group of cells for upper limb muscles Substantia gelatinosa present, continuous with Sp.N. of cranial nerve V at level C2; nucleus proprius present; nucleus dorsalis (Clarke column) absent Absent Thoracic Round Fasciculus cuneatus (T1-T6) and fasciculus gracilis present Medial group of cells for trunk muscles Substantia gelatinosa, nucleus proprius, and visceral afferent nucleus present. Present; gives rise to preganglionic sympathetic fibers Lumbar Round to oval Fasciculus cuneatus absent; fasciculus gracilis present Medial group of cells for lower limb muscles; central group of cells for lumbosacral nerve Substantia gelatinosa, nucleus proprius, nucleus dorsalis (Clarke column) at L1-L4, and visceral afferent nucleus present Present (L1-L2 [3]); gives rise to preganglionic sympathetic fibers Sacral Round Small amount; fasciculus cuneatus absent; fasciculus gracilis present Medial group of cells for lower limb and perineal muscles Substantia gelatinosa and nucleus proprius present Absent; group of cells present at S2-S4, for parasympathetic outflow</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A woman is admitted to the hospital complaining of severe back pain. Radiographic examination reveals that the L4 vertebral body has slipped anteriorly, with a fracture of the zygapophysial joint What is the proper name of this condition?", "options": [{"label": "A", "text": "Spondylolisthesis.", "correct": true}, {"label": "B", "text": "Spondylolysis", "correct": false}, {"label": "C", "text": "Crush vertebral fracture", "correct": false}, {"label": "D", "text": "Intervertebral disk herniation", "correct": false}], "correct_answer": "A. Spondylolisthesis.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392379058-QTDA065011IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Spondylolisthesis. Spondylolisthesis is an anterior displacement created by an irregularity in the anterior margin of the vertebral column such that L5 and the overlying L4 (and sometimes L3) protrude forward. Spondylolisthesis most commonly occurs at the L5-S1 level with the anterior translation of the L5 vertebral body on the S1 vertebral body. The L4-5 level is the second most common location for spondylolisthesis.</p>\n<p><strong>Highyeild:</strong></p><p>A hangman's fracture is a specific type of spondylolisthesis where the second cervical vertebra (C2) is displaced anteriorly relative to the C3 vertebra due to fractures of the C2 vertebra's pedicles .</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option:B. Spondylolysis Spondylolysis is a defect or stress fracture in the pars interarticularis of the vertebral arch.The vast majority of cases occur in the lower lumbar vertebrae (L5), but spondylolysis may also occur in the cervical vertebrae. Option:C. Crush vertebral fracture Crush vertebral fracture is a collapse of vertebral bodies as a result of trauma. Option:D. Intervertebral disk herniation Intervertebral disc herniations occur when the nucleus pulposus protrudes through the annulus fibrosus into the intervertebral foramen or the vertebral canal. The most common protrusion is posterolaterally, where the annulus fibrosus is not reinforced by the posterior longitudinal ligament. Klippel-Feil syndrome results from an abnormal number of cervical vertebral bodies</p>\n<p><strong>Extraedge:</strong></p><p>Spondylolysis is typically caused by a stress fracture of the bone, and is especially common in adolescents who over-train in activities. The pars interarticularis is vulnerable to fracture during spinal hyperextension, especially when combined with rotation, or when experiencing a force during a landing. This stress fracture most commonly occurs where the concave lumbar spine transitions to the convex sacrum (L5-S1). A significant number of individuals with spondylolysis will develop spondylolisthesis, which is true for 50-81% of this population.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 29-year-old female was lifting heavy weights during an intense training session. The athlete felt severe pain radiate suddenly to the posterior aspect of her right thigh and leg. The patient was taken to the hospital where an MRI was performed . Which nerve was most probably affected.", "options": [{"label": "A", "text": "L3", "correct": false}, {"label": "B", "text": "L4", "correct": false}, {"label": "C", "text": "L2", "correct": false}, {"label": "D", "text": "L5", "correct": true}], "correct_answer": "D. L5", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/QTDA065012IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>L5 In this MRI, a posterolateral herniation between L4/L5 exists. In the lumbar region, spinal nerves exit the vertebral column below their named vertebrae. In an L4/L5 intervertebral disk herniation, the L5 spinal nerve would be affected as it descends between L4/L5 vertebrae to exit below the L5 level.</p>\n<p><strong>Highyeild:</strong></p><p>Herniation of intervertebral discs The discs between the vertebrae comprises a central portion (the nucleus pulposus) and a complex series of fibrous rings (annulus fibrosus). A tear can occur within the annulus fibrosus through which the material of the nucleus pulposus can track. After a period of time, this material may track into the vertebral canal or into the intervertebral foramen to impinge on neural structures. This is a common cause of back pain. Depending on the level, a disc may protrude posteriorly to directly impinge on the cord or the roots of the lumbar nerves or may protrude posterolaterally adjacent to the pedicle and impinge on the descending root.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option: A. L3 Option: B. L4 Option: C. L2 In this MRI a posterolateral herniation between L4/L5 exists. In the lumbar region, spinal nerves exit the vertebral column below their named vertebrae. In an L4/L5 intervertebral disk herniation, the L5 spinal nerve would be affected as it descends between L4/L5 vertebrae to exit below the L5 level. Therefore L3,L4 and L2 are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>In cervical regions of the vertebral column, cervical disc protrusions often become ossified and are termed disc osteophyte bars.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are features of LMN lesion except:", "options": [{"label": "A", "text": "Babinski Sign Negative", "correct": false}, {"label": "B", "text": "Absent DTR", "correct": false}, {"label": "C", "text": "Hypertonia", "correct": true}, {"label": "D", "text": "Hypotonia", "correct": false}], "correct_answer": "C. Hypertonia", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Hypertonia Damage to UMN's leads to a characteristic set of clinical symptoms known as the upper motor neuron syndrome. These symptoms can include weakness, spasticity, clonus, and hyperreflexia.</p>\n<p><strong>Highyeild:</strong></p><p>LMN paralysis UMN paralysis Muscle tone abolished Leads to flaccid paralysis Muscles atrophy later Reaction of degeneration seen Tendon reflexes absent Limited damage Ipsilateral Babinski sign negative All superficial and deep reflexes lost due to damage to motor pathways May affect single muscle group as in poliomyelitis and Bell's palsy Muscle tone increased Leads to spastic paralysis No atrophy of muscles Reaction of degeneration not seen Tendon reflexes exaggerated Extensive damage Mostly contralateral Babinski sign positive Superficial reflexes, like abdominal, cremasteric, plantar, are lost due to damage to corticospinal tracts Affects many groups of muscles as in hemiplegia. Damage to corticospinal tract removes the inhibitory effect on the superficial reflexes, resulting in Babinski positive sign There is loss of control on lower motor neurons, which become hyperactive, leading to spastic paralysis</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Babinski Sign Negative Option: B. Absent DTR Option: D. Hypotonia All are features of LMN Lesion.</p>\n<p><strong>Extraedge:</strong></p><p>Comparison of pyramidal and extrapyramidal tracts Pyramidal tracts Extrapyramidal tracts Recent in evolution Older in evolution These comprise only cortico- spinal and corticonuclear tracts These comprise olivospinal, vestibulospinal, tectospinal, reticulospinal, rubrospinal tracts Origin from motor cortex These arise from olivary vesti- bular, tectum (collicular), reticular and red nuclei The impulse passes directly to anterior horn cells Impulse passes by polysynaptic route via cortex, basal ganglia, cerebellum and brainstem Function is to perform voluntary skilled movement Control tone and equilibrium. These facilitate/inhibit flexor/ extensor reflexes Injury leads to increased muscle tone and loss of motor activity Injury leads to increased muscle tone with clasp knife rigidity</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which is not a finding in a patient of Brown Sequard syndrome:", "options": [{"label": "A", "text": "Hemisection of spinal cord", "correct": false}, {"label": "B", "text": "Ipsilateral upper motor neuron paralysis below the level of lesion", "correct": false}, {"label": "C", "text": "Ipsilateral loss of pain and temperature below the level of lesion", "correct": true}, {"label": "D", "text": "Ipsilateral lower motor neuron paralysis at the level of lesion", "correct": false}], "correct_answer": "C. Ipsilateral loss of pain and temperature below the level of lesion", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ipsilateral loss of pain and temperature below the level of lesion Brown-Séquard syndrome: This is caused due to hemisection of the spinal cord. Below the level of lesion: Ipsilateral upper motor neuron paralysis caused by pyramidal tract damage. Ipsilateral loss of conscious proprioceptive sensations caused due to damage to the posterior white column. Contralateral loss of pain and temperature and touch caused due to damage to lateral spinothalamic and anterior spinothalamic tracts. At the level of lesion: Ipsilateral lower motor neuron paralysis caused due to damage to ventral nerve roots. Ipsilateral anesthesia over the skin of the segment due to injury to the ventral nerve roots. Above the level: Ipsilateral hyperaesthesia above the level of the lesion due to irritation of dorsal nerve roots. Brown-Séquard syndrome:</p>\n<p><strong>Highyeild:</strong></p><p>Brown-Séquard syndrome may be caused by injury to the spinal cord resulting from a spinal cord tumor, trauma [such as a fall or injury from gunshot or puncture to the cervical or thoracic spine], ischemia (obstruction of a blood vessel), or infectious or inflammatory diseases such as tuberculosis, or multiple sclerosis. As a result of the injury to these three main brain pathways the patient will present with three lesions: The corticospinal lesion produces spastic paralysis on the same side of the body below the level of the lesion (due to loss of moderation by the UMN). At the level of the lesion, there will be flaccid paralysis of the muscles supplied by the nerve of that level (since lower motor neurons are affected at the level of the lesion). The lesion to fasciculus gracilis or fasciculus cuneatus (dorsal column) results in ipsilateral loss of vibration and proprioception (position sense) as well as loss of all sensation of fine touch. The loss of the spinothalamic tract leads to pain and temperature sensation being lost from the contralateral side beginning one or two segments below the lesion.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. Hemisection of spinal cord Option:B. Ipsilateral upper motor neuron paralysis below the level of lesion Option:D. Ipsilateral lower motor neuron paralysis at the level of lesion All the features mentioned in option A, B and D are present in case of Brown-Séquard syndrome, therefore option A,B and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Brown-Séquard syndrome is caused by damage to one half of the spinal cord, i.e. hemisection of the spinal cord resulting in paralysis and loss of proprioception on the same (or ipsilateral) side as the injury or lesion, and loss of pain and temperature sensation on the opposite (or contralateral) side as the lesion.In addition, if the lesion occurs above T1 of the spinal cord it will produce ipsilateral Horner's syndrome with involvement of the oculosympathetic pathway.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In lumbar puncture, all of the following structures are pierced by the needle except:", "options": [{"label": "A", "text": "Posterior Longitudinal Ligament", "correct": true}, {"label": "B", "text": "Ligamentum flavum", "correct": false}, {"label": "C", "text": "Interspinous ligament", "correct": false}, {"label": "D", "text": "Supraspinous ligament", "correct": false}], "correct_answer": "A. Posterior Longitudinal Ligament", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior Longitudinal Ligament Posterior and anterior longitudinal ligaments are not pierced in lumbar puncture. A sagittal section illustrating the course of a lumbar puncture needle through the skin, subcutaneous tissue, supraspinous ligament, an interspinous ligament between the spinous processes, ligamentum flavum, dura mater, into the subarachnoid space and between the nerve roots of the cauda equina.</p>\n<p><strong>Highyeild:</strong></p><p>The Lumbar Puncture needle pierces in order: skin, subcutaneous tissue, supraspinous ligament, interspinous ligament, ligamentum flavum, epidural space containing the internal vertebral venous plexus, dura, arachnoid, and finally the subarachnoid space</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Ligamentum flavum Option: C. Interspinous ligament Option: D. Supraspinous ligament Ligamentum flavum, Interspinous ligament, and Supraspinous ligament all are pierced during a lumbar puncture.</p>\n<p><strong>Extraedge:</strong></p><p>Lumbar puncture ( LP ), also known as a spinal tap , is a medical procedure in which a needle is inserted into the spinal canal, most commonly to collect cerebrospinal fluid (CSF) for diagnostic testing. The main reason for a lumbar puncture is to help diagnose central nervous system diseases, including the brain and spine. Examples of these conditions include meningitis and subarachnoid hemorrhage. It may also be used therapeutically in some conditions. Increased intracranial pressure (pressure in the skull) is a contraindication due to the risk of brain matter being compressed and pushed toward the spine.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Popping sensation/slight loss of resistance after that is doing the lumbar puncture is felt due to piercing of:", "options": [{"label": "A", "text": "Ligamentum Flavum", "correct": true}, {"label": "B", "text": "Supraspinous ligament", "correct": false}, {"label": "C", "text": "Interspinous ligament", "correct": false}, {"label": "D", "text": "Duramater", "correct": false}], "correct_answer": "A. Ligamentum Flavum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ligamentum Flavum The lumbar puncture needle may be inserted in the midline or just to one side, and angled in the horizontal and sagittal planes sufficiently to pierce the ligamentum flavum in or very near the midline. There is then a slight loss of resistance as the needle enters the epidural space; careful advancement would next pierce the dura and arachnoid to release CSF.</p>\n<p><strong>Highyeild:</strong></p><p>A pop sound during lumbar puncture may be palpable as the needle pierces the ligamentum flavum (to enter the epidural space) and sometimes when the needle pierces the dura (to enter the subarachnoid space). In children, such pops are usually less apparent.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Supraspinous ligament Option: C. Interspinous ligament Option: D. Duramater A pop sound during lumbar puncture may be palpable as the needle pierces the ligamentum flavum (to enter the epidural space) and sometimes when the needle pierces the dura (to enter the subarachnoid space), therefore Option B, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>A diagnostic Lumbar Puncture should be performed at the L3/4 interspinal space. The approximate distance from the skin to the epidural space is 45-55mm and the dura mater may be up to 7mm beyond that depth.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Denticulate ligaments has how many pairs of teeth-like projections:", "options": [{"label": "A", "text": "19", "correct": false}, {"label": "B", "text": "21", "correct": true}, {"label": "C", "text": "28", "correct": false}, {"label": "D", "text": "3", "correct": false}], "correct_answer": "B. 21", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>21 The pia mater of the spinal cord has a pair of denticulate ligaments (one on each side of the spinal cord) with 21 pairs of tooth-like projections that attach it to the arachnoid and dura mater.</p>\n<p><strong>Highyeild:</strong></p><p>Ligamenta denticulata are 21 pairs of teeth-like projections. They fuse laterally with the arachnoid, and dura maters midway between the exits of the roots of adjacent spinal nerves. The highest process attaches immediately superior to the foramen magnum. The ligamentum denticulatum keeps the spinal cord in position. Ligamenta denticulata</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. 19 Option: C. 28 Option: D. 3 Denticulate ligaments (one on each side of the spinal cord) with 21 pairs of tooth-like projections which attach it to the arachnoid and dura mater, therefore Option A, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Linea splendens is a thickening seen at the anteromedial sulcus in the lower part of the spinal cord.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All are true about conus medullaris syndrome, except:", "options": [{"label": "A", "text": "Sexual Dysfunction", "correct": false}, {"label": "B", "text": "Late bladder and bowel involvement", "correct": true}, {"label": "C", "text": "Early bladder and bowel involvement", "correct": false}, {"label": "D", "text": "Perianal anaesthesia", "correct": false}], "correct_answer": "B. Late bladder and bowel involvement", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Late bladder and bowel involvement Conus medullaris syndrome typically presents with symmetric saddle/perianal anaesthesia, symmetric motor deficit, and earlier atonic bladder and sphincter dysfunction. The usual causes are intradural tumors or vascular lesions.</p>\n<p><strong>Highyeild:</strong></p><p>Cauda equina syndrome typically presents in men who have a lumbar disc herniation in the setting of lumbar spinal stenosis, with symptoms of asymmetric saddle anaesthesia and asymmetric lower extremity weakness, and delayed presentation of atonic bladder and flaccid anal sphincter. The conus medullaris syndrome occurs due to compression of conus medullaris, the caudal part of the spinal cord containing sacral and coccygeal spinal segments; while the cauda equina syndrome occurs due to compression of cauda equina.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Sexual Dysfunction Option: C. Early bladder and bowel involvement Option: D. Perianal anesthesia Sexual Dysfunction, Early bladder and bowel involvement, and Perianal anesthesia, all are features of conus medullaris syndrome.</p>\n<p><strong>Extraedge:</strong></p><p>The differences between these two syndromes, are given in the box below: Conus medullary syndrome Cauda equina syndrome Sudden onset Gradual onset Perianal anesthesia Saddle anesthesia Early bladder and bowel involvement Late bladder and bowel involvement Low back pain severe Low back pain, not severe Root pain not severe Root pain severe Sexual dysfunction more frequent Sexual dysfunction less frequent Both UMN and LMN type of paralysis Only LMN type of paralysis</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 28 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "In the coronary bypass graft surgery of a 49-year-old woman, the internal thoracic artery is used as the coronary artery bypass graft. The anterior intercostal arteries in intercostal spaces three to six are ligated. Which of the following arteries will be expected to supply these intercostal spaces?", "options": [{"label": "A", "text": "Musculophrenic", "correct": false}, {"label": "B", "text": "Superior epigastric", "correct": false}, {"label": "C", "text": "Posterior intercostal", "correct": true}, {"label": "D", "text": "Lateral thoracic", "correct": false}], "correct_answer": "C. Posterior intercostal", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior intercostal The anterior intercostal arteries are anastomose with the posterior intercostal arteries. Ligation of the anterior arteries would not affect the supply of the intercostal spaces because the posterior arteries would provide collateral arterial supply.</p>\n<p><strong>Highyeild:</strong></p><p>Arteries of the thoracic wall. Posterior intercostal arteries originate from vessels associated with the posterior thoracic wall. The upper two posterior intercostal arteries on each side are derived from the supreme intercostal artery, which descends into the thorax as a branch of the costocervical trunk in the neck. The costocervical trunk is a posterior branch of the subclavian artery The remaining nine pairs of posterior intercostal arteries arise from the posterior surface of the thoracic aorta. Arteries of the thoracic wall.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A- Branches of the musculophrenic artery provide supply for the lower seventh, eighth, and ninth intercostal spaces. Option:B - The superior epigastric artery passes into the rectus sheath of the anterior abdominal wall. Option:D - The lateral thoracic artery arises from the second part of the axillary artery, and the thoracodorsal artery is a branch of the subscapular artery, a branch of the third part of the axillary artery.</p>\n<p><strong>Extraedge:</strong></p><p>The anterior intercostal arteries originate directly or indirectly as lateral branches from the internal thoracic arteries.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 33-year-old man is admitted to the hospital after a multiple Car collision. His blood pressure is 89/39 mm Hg, and a central venous line is placed. Which of the following structures is used as a landmark to verify that the tip of the catheter of the central venous line is in the correct place?", "options": [{"label": "A", "text": "Carina", "correct": true}, {"label": "B", "text": "Subclavian artery", "correct": false}, {"label": "C", "text": "Superior vena cava", "correct": false}, {"label": "D", "text": "Left atrium", "correct": false}], "correct_answer": "A. Carina", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Carina The carina is the only answer listed that can easily be seen in the The carina is at the level of T4 to T5 (plane associated with the sternal angle of Louis). This landmark is commonly used to guide the placement of a central venous line. Carina</p>\n<p><strong>Highyeild:</strong></p><p>The carina is a cartilaginous ridge separating the left and right main bronchi that are formed by the inferior-ward and posterior-ward prolongation of the inferior-most tracheal cartilage. The carina occurs at the lower end of the trachea - usually at the level of the 4th to 5th thoracic vertebra. This is in line with the sternal angle, but the carina may raise or descend up to two vertebrae higher or lower with breathing. The carina lies to the left of the midline and runs anteroposteriorly (front to back).</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Options B,C,D - These are not visible on a plain radiograph.</p>\n<p><strong>Extraedge:</strong></p><p>The carina is around the area posterior to where the aortic arch crosses to the left of the trachea. The azygos vein crosses right to the trachea above the carina.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 59-year-old man is admitted to the hospital with a severe inferior myocardial infarction. The patient was brought to the catheterization lab for an emergency catheterization of his coronary arteries. During the passage of the catheter from his right radial artery it is noted that the patient has a right subclavian artery passing posteriorly to the esophagus and thus requires a longer catheter. Which of the following structures failed to regress in this condition?", "options": [{"label": "A", "text": "Right dorsal aorta distal to the seventh intersegmental artery", "correct": true}, {"label": "B", "text": "Left dorsal aorta distal to the seventh intersegmental artery", "correct": false}, {"label": "C", "text": "Right dorsal aorta proximal to the seventh intersegmental artery", "correct": false}, {"label": "D", "text": "Fifth arch artery", "correct": false}], "correct_answer": "A. Right dorsal aorta distal to the seventh intersegmental artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Right dorsal aorta distal to the seventh intersegmental artery Right subclavian artery - arises from the right fourth aortic arch proximally, the right seventh intersegmental artery distally.</p>\n<p><strong>Highyeild:</strong></p><p>Venous access for central and dialysis lines Large systemic veins are used to establish central venous access for administering large amounts of fluid, drugs, and blood. Most of these lines (small-bore tubes) are introduced through the venous puncture into the axillary, subclavian, or internal jugular veins. The lines are then passed through the main veins of the superior mediastinum, with the tips of the lines usually residing in the distal portion of the superior vena cava or the right atrium.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B - No known specific pathology occurs in this conditio Option: C - If the fourth pharyngeal arch artery and the right dorsal aorta disappear cranial to the seventh segmental artery the right subclavian artery will be retroesophageal. In this case, the right subclavian artery is formed by the right seventh intersegmental artery and the distal dorsal aorta, which does not regress. Option:D - Fifth arch regresses normally.</p>\n<p><strong>Extraedge:</strong></p><p>Using the superior vena cava to access the inferior vena cava Because the superior and inferior venae cavae are oriented along the same vertical axis, a guidewire, catheter, or line can be passed from the superior vena cava through the right atrium and into the inferior vena cava. This is a common route of access for such procedures as: transjugular liver biopsy, transjugular intrahepatic portosystemic shunts (TIPS), and insertion of an inferior vena cava filter to catch emboli dislodged from veins in the lower limb and pelvis (i.e., patients with deep vein thrombosis [DVT]).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 10-year-old boy is admitted to the hospital with retrosternal discomfort. A CT scan reveals a midline tumor of the thymus gland. Which of the following veins would most likely be compressed by the tumor?", "options": [{"label": "A", "text": "Right Internal Jugular", "correct": false}, {"label": "B", "text": "Left internal jugular", "correct": false}, {"label": "C", "text": "Subclavian", "correct": false}, {"label": "D", "text": "Left brachiocephalic", "correct": true}], "correct_answer": "D. Left brachiocephalic", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left brachiocephalic The thymus lies in the superior mediastinum and extends upward into the neck, especially in the young. A midline tumor is more likely to cause compression of the left brachiocephalic vein, which crosses the midline than the right brachiocephalic vein, which is not located in the midline.</p>\n<p><strong>Highyeild:</strong></p><p>The major structures found in the superior mediastinum includes: thymus, right and left brachiocephalic veins, left superior intercostal vein, superior vena cava, arch of the aorta with its three large branches, trachea, esophagus, phrenic nerves, vagus nerves, left recurrent laryngeal branch of the left vagus nerve, thoracic duct, and other small nerves, blood vessels, and lymphatics. Structures in the superior mediastinum</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A,B - The internal jugular veins are located superior and lateral to the position of the thymus gland. Option: C - The subclavian vein is distal or lateral to this location, and the thymus gland would not likely impinge upon it.</p>\n<p><strong>Extraedge:</strong></p><p>Ectopic parathyroid glands in the thymus The parathyroid glands develop from the third pharyngeal pouch, which also forms the thymus. The thymus is, therefore, a common site for ectopic parathyroid glands and, potentially, ectopic parathyroid hormone production.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 47-year-old woman is admitted to the hospital with pain in her neck. During physical examination, it is observed that the thyroid gland is enlarged and displacing the trachea. A biopsy reveals a benign tumor. A CT scan examination reveals tracheal deviation to the left. Which of the following structures will most likely be compressed as a result of the deviation?", "options": [{"label": "A", "text": "Left Brachiocephalic Vein", "correct": true}, {"label": "B", "text": "Left internal jugular vein", "correct": false}, {"label": "C", "text": "Left subclavian artery", "correct": false}, {"label": "D", "text": "Right internal jugular vein", "correct": false}], "correct_answer": "A. Left Brachiocephalic Vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left Brachiocephalic Vein A left tracheal deviation with an enlarged thyroid gland will most likely compress the left brachiocephalic vein. Structures in the superior mediastinum</p>\n<p><strong>Highyeild:</strong></p><p>The left brachiocephalic vein begins posterior to the medial end of the left clavicle. It crosses to the right, moving in a slightly inferior direction, and joins with the right brachiocephalic vein to form the superior vena cava posterior to the lower edge of the right first costal cartilage close to the right sternal border. Venous tributaries include the vertebral, first posterior intercostal, left superior intercostal, inferior thyroid, and internal thoracic veins. It may also receive thymic and pericardial veins. The left brachiocephalic vein crosses the midline posterior to the manubrium in the adult. In infants and children, the left brachiocephalic vein rises above the superior border of the manubrium and therefore is less protected.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A,B - The internal jugular veins are located superior and lateral to the position of the thymus gland. Option: C - The subclavian vein is distal or lateral to this location, and the thymus gland would not likely impinge upon it.</p>\n<p><strong>Extraedge:</strong></p><p>The right brachiocephalic vein begins posterior to the medial end of the right clavicle and passes vertically downward, forming the superior vena cava when it is joined by the left brachiocephalic vein. Venous tributaries include the vertebral, first posterior intercostal, and internal thoracic veins. The inferior thyroid and thymic veins may also drain into it.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 33-year-old man is admitted to the hospital with severe traumatic injuries. His blood pressure is 89/39 mm Hg, and a central venous line is placed. Which of the following injuries is most likely to occur when a subclavian central venous line procedure is performed?", "options": [{"label": "A", "text": "Penetration of the subclavian artery", "correct": true}, {"label": "B", "text": "Injury of the phrenic nerve", "correct": false}, {"label": "C", "text": "Penetration of the superior vena cava", "correct": false}, {"label": "D", "text": "Penetration of the left common carotid artery", "correct": false}], "correct_answer": "A. Penetration of the subclavian artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Penetration of the subclavian artery The subclavian artery lies directly posterior to the subclavian vein; therefore, it is the structure that would be most vulnerable to damage when placing a central venous line in the subclavian vein. The left vagus nerve also gives rise to the left recurrent laryngeal nerve, which arises from it at the inferior margin of the arch of the aorta just lateral to the ligamen tum arteriosum.</p>\n<p><strong>Highyeild:</strong></p><p>The left recurrent laryngeal nerve passes inferior to the arch of the aorta before ascending on its medial surface. Entering a groove between the trachea and esophagus, the left recurrent laryngeal nerve continues superiorly to enter the neck and terminate in the larynx. Left subclavian artery through the superior mediastinum.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: B - Both the phrenic and vagus nerves will be medial to the placement of the line and are not likely to be damaged. Option:C- The superior vena cava lies medial and inferior to the site of placement and is too deep to be easily damaged. Option:D - The common carotid artery is also too medial to be damaged by the line.</p>\n<p><strong>Extraedge:</strong></p><p>The left recurrent laryngeal nerve is a branch of the left vagus nerve. It passes between the pulmonary artery and the aorta, a region known clinically as the aortopulmonary window, and may be compressed in any patient with a pathological mass in this region. This compression results in vocal cord paralysis and hoarseness of the voice. Lymph node enlargement, often associated with the spread of lung cancer, is a common condition that may produce compression. Chest radiography is therefore usually carried out for all patients whose symptoms include a hoarse voice.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 34-year-old unconscious patient is admitted to the hospital. His blood pressure is 85/45 mm Hg. A central venous line is placed. During the subsequent radiologic examination, a chylothorax is detected. Which of the following structures was most likely accidentally damaged during the placement of the central venous line?", "options": [{"label": "A", "text": "Left external jugular vein", "correct": false}, {"label": "B", "text": "Site of origin of the left brachiocephalic vein", "correct": true}, {"label": "C", "text": "Right subclavian vein", "correct": false}, {"label": "D", "text": "Proximal part of the right brachiocephalic vein", "correct": false}], "correct_answer": "B. Site of origin of the left brachiocephalic vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Site of origin of the left brachiocephalic vein Chylothorax is usually caused by injury to the thoracic duct. The thoracic duct enters the venous system at the junction of the left internal jugular vein and the left subclavian vein, where they form the left brachiocephalic vein. Penetrating injuries at the beginning of the left brachiocephalic vein commonly also disrupt the termination of the thoracic duct.</p>\n<p><strong>Highyeild:</strong></p><p>At the vertebral level, T-V, The thoracic duct moves to the left of the midline and enters the superior mediastinum. It continues through the superior mediastinum and into the neck. After being joined, in most cases, by the left jugular trunk, which drains the left side of the head and neck, and the left subclavian trunk, which drains the left upper limb, the thoracic duct empties into the junction of the left subclavian and left internal jugular veins. Thoracic duct</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option: A - Injury to the left external jugular vein is not associated with chylothorax. Option: C - Injury to the right subclavian vein is not associated with chylothorax. Option:D- Injury to the Proximal part of right brachiocephalic vein is not associated with chylothorax.</p>\n<p><strong>Extraedge:</strong></p><p>The thoracic duct is the principal channel through which lymph from most of the body is returned to the venous system. It begins as a confluence of lymph trunks in the abdomen, sometimes forming a saccular dilation referred to as the cisterna chyli (chyle cistern), which drains the abdominal viscera and walls, pelvis, perineum, and lower limbs. The thoracic duct extends from vertebra L-II to the root of the neck.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "The given histological image shows the spinal cord. Which of the following statements with respect to the given image is correct?", "options": [{"label": "A", "text": "The structure marked by a black arrow is the sensory root", "correct": false}, {"label": "B", "text": "The structure marked by a blue arrow is responsible for the autonomic supply.", "correct": false}, {"label": "C", "text": "The structure marked by an orange arrow is the efferent pathway.", "correct": false}, {"label": "D", "text": "All of the above", "correct": true}], "correct_answer": "D. All of the above", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392860176-QTDA066001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>All of the above In the given question, the structure marked are: Option: A. The structure marked by black arrow is the sensory root Black arrow- dorsal horn, the sensory root, is responsible for the afferent pathway. Option: B. The structure marked by a blue arrow is responsible for the autonomic supply. Blue arrow- lateral horn is responsible for the autonomic supply. It is present only in those parts of the spinal cord where sympathetic or parasympathetic nerves originate. Option: C . The structure marked by an orange arrow is the efferent pathway. The orange arrow shows the ventral horn responsible for the motor pathway. Hence, all the statements are correct.</p>\n<p><strong>Highyeild:</strong></p><p>Spinal Cord Structure The spinal cord is composed of an inner core of gray matter surrounded by an outer covering of white matter; there is no indication that the cord is segmented. Transverse section of the spinal cord at different levels</p>\n<p><strong>Extraedge:</strong></p><p>Comparison of Structural Details in Different Regions of the Spinal Cord Region Shape White Matter Gray Matter Anterior Gray Column Posterior Gray Column Lateral Gray Column Cervical Oval Fasciculus cuneatus and fasciculus gracilis present Medial group of cells for neck muscles; central group of cells for accessory nucleus (C1-C5) and phrenic nucleus (C3-C5); lateral group of cells for upper limb muscles Substantia gelatinosa present, continuous with Sp.N. of cranial nerve V at level C2; nucleus proprius present; nucleus dorsalis (Clarke column) absent Absent Thoracic Round Fasciculus cuneatus (T1-T6) and fasciculus gracilis present Medial group of cells for trunk muscles Substantia gelatinosa, nucleus proprius, and visceral afferent nucleus present. Present; gives rise to preganglionic sympathetic fibers Lumbar Round to oval Fasciculus cuneatus absent; fasciculus gracilis present Medial group of cells for lower limb muscles; central group of cells for lumbosacral nerve Substantia gelatinosa, nucleus proprius, nucleus dorsalis (Clarke column) at L1-L4, and visceral afferent nucleus present Present (L1-L2 [3]); gives rise to preganglionic sympathetic fibers Sacral Round Small amount; fasciculus cuneatus absent; fasciculus gracilis present Medial group of cells for lower limb and perineal muscles Substantia gelatinosa and nucleus proprius present Absent; group of cells present at S2-S4, for parasympathetic outflow</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following types of fiber travel through white rami communicans?", "options": [{"label": "A", "text": "Preganglionic Non-Myelinated Fibers", "correct": false}, {"label": "B", "text": "Preganglionic myelinated fibers", "correct": true}, {"label": "C", "text": "Post ganglionic non-myelinated fibers", "correct": false}, {"label": "D", "text": "Post ganglionic myelinated fibers", "correct": false}], "correct_answer": "B. Preganglionic myelinated fibers", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Preganglionic myelinated fibers In the given question, the fibers that travel through white rami communicans are mostly myelinated and preganglionic. After relaying in the sympathetic ganglion, the post-ganglionic fibers will travel through gray rami communicans which mostly contain non-myelinated fibers. White rami communicans can also have non-myelinated fibers when carrying general sensation from the viscera. Hence the correct answer to this question is option B.</p>\n<p><strong>Highyeild:</strong></p><p>The white rami communicantes are the preganglionic sympathetic outflow from the spinal cord. The cell bodies for the preganglionic sympathetic myelinated fibers in the white rami communicantes lie in the ipsilateral intermediolateral cell column in the spinal cord, which extends from T1-L2. These rami also contain general visceral afferent fibers (sensory from the organs) whose primary cell bodies reside in dorsal root ganglia (which then synapse in the dorsal horn). The preganglionic sympathetic fibers will enter the sympathetic trunk and either synapse at the ganglion on the same level or travel up or down the sympathetic trunk to arrive at the correct spinal level for their action. Once they synapse in the sympathetic ganglion in the sympathetic trunk, they exit the trunk as gray rami to join the spinal nerve and innervate the appropriate structure.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Preganglionic Non-Myelinated Fibers Option: C. Post ganglionic non-myelinated fibers Option: D. Post ganglionic myelinated fibers Options A, C, and D are incorrect answers because the white rami communicantes are the preganglionic sympathetic outflow from the spinal cord and are myelinated.</p>\n<p><strong>Extraedge:</strong></p><p>On the cross-section of the spinal cord, the gray matter is seen as an H-shaped pillar with anterior and posterior gray columns or horns, united by a thin gray commissure containing the small central canal. A small lateral gray column or horn is present in the cord's thoracic and upper lumbar segments. The amount of gray matter present at any given spinal cord level is related to the amount of muscle Innervated at that level. Thus, its size is greatest within the cervical and lumbosacral enlargements of the cord, which innervate the muscles of the upper and lower limbs, respectively.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "While studying various ganglions in our body, you learned that these ganglions supply the smooth muscle, the arrector pili muscle. Which of the following columns is associated with this type of supply?", "options": [{"label": "A", "text": "General Visceral Afferent", "correct": false}, {"label": "B", "text": "General somatic efferent", "correct": false}, {"label": "C", "text": "General visceral efferent", "correct": true}, {"label": "D", "text": "General somatic afferent", "correct": false}], "correct_answer": "C. General visceral efferent", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>General visceral efferent The autonomic supply from the lateral horn travels through the white rami communicans and relays in a sympathetic chain, ultimately giving post-ganglionic non-myelinated fibers that travel through gray rami communicans. These post-ganglionic fibers supply the smooth muscles of the blood vessels and the arrector pili muscle. Hence it is included in the column of general visceral efferent. Gray and white rami communicans</p>\n<p><strong>Highyeild:</strong></p><p>Each arrector pili comprises a bundle of smooth muscle fibers that attach to several follicles (a follicular unit). The sympathetic division of the autonomic nervous system innervates each. The muscle attaches to the follicular stem cell niche in the follicular bulge, splitting at its deep end to encircle the follicle. The contraction of the muscle is involuntary. Stress, such as cold, fear, etc., may stimulate the sympathetic nervous system and thus cause muscle contraction.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option: A. General Visceral Afferent Option: B. General somatic efferent Option: D . General somatic afferent General visceral efferent fibers (GVE) or visceral efferents, or autonomic efferents, are the efferent nerve fibers of the autonomic nervous system (also known as the visceral efferent nervous system that provides motor innervation to smooth muscle (arrector pili muscle), cardiac muscle , and glands , therefore Option A, B and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Organ Sympathetic Action Parasympathetic Action Eye Pupil Dilates Constricts Ciliary muscle Relaxes Contracts Glands Lacrimal, parotid, submandibular, sublingual, nasal Reduce secretion by causing vasoconstriction of blood vessels Increase secretion Sweat Increases secretion Heart Cardiac muscle Increases force of contraction Decreases force of contraction Coronary arteries (mainly controlled by local metabolic factors) Dilates (ẞ receptors), constricts (a receptors) Lung Bronchial muscle Relaxes (dilates bronchi) Contracts (constricts bronchi) Bronchial secretion Increases secretion Bronchial arteries Constricts Dilates Gastrointestinal tract Muscle in walls Decreases peristalsis Increases peristalsis Muscle in sphincters Contracts Relaxes Glands Reduces secretion by vasoconstriction of blood vessels Increases secretion Liver Breaks down glycogen into glucose Gallbladder Relaxes Contracts Kidney Decreases output due to constriction of arteries Urinary bladder Bladder wall (detrusor) Relaxes Contracts Sphincter vesicae Contracts Relaxes Erectile tissue of penis and clitoris Relaxes, causes erection Ejaculation Contracts smooth muscle of vas deferens, seminal vesicles, and prostate Systemic arteries Skin Constrict Abdominal Constrict Muscle Constrict (a receptors), dilate (ẞ receptors), dilate (cholinergic) rector pili muscle Contract prarenal Cortex Stimulates Medulla Liberates epinephrine and norepinephrine</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During autonomic supply to various organs in the body, the post-sympathetic fibers arise from the sympathetic ganglion supplying them. What is the extent of the level where the preganglionic sympathetic neuron cell bodies are located?", "options": [{"label": "A", "text": "T1-T12", "correct": false}, {"label": "B", "text": "T7-L2", "correct": false}, {"label": "C", "text": "T1-L5", "correct": false}, {"label": "D", "text": "T1-L2", "correct": true}], "correct_answer": "D. T1-L2", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>T1-L2 In the given question, as asked, the cell bodies of the preganglionic sympathetic fiber are located from T1-L2. This level represents the sympathetic outflow, also known as thoracolumbar Hence, the correct answer is option D.</p>\n<p><strong>Highyeild:</strong></p><p>The sympathetic nervous system consists of cells with bodies in the lateral gray column from T1 to L2/3. These cell bodies are \"GVE\" (general visceral efferent) neurons and are the preganglionic neurons.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. T1-T12 Option: B. T7-L2 Option: C. T1-L5 In the given question, as asked, the cell bodies of the preganglionic sympathetic fiber are located from T1-L2. This level represents the sympathetic outflow, also known as thoracolumbar Hence, Options A, B, and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The parasympathetic nervous system consists of cells with bodies in one of two locations: the brainstem (Cranial Nerves III, VII, IX, X) or the sacral spinal cord (S2, S3, S4).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In the given image, the following structure is marked, which forms the important part of the outflow from the sympathetic chain. Which of the following neurons supplying different parts of the body does not travel through this structure? General sensation from the viscera. General sensation from the skin. Sympathetic supply to the coeliac ganglion. General supply to the glands. Select the correct answer from the given below code:", "options": [{"label": "A", "text": "A, C", "correct": false}, {"label": "B", "text": "B, C", "correct": true}, {"label": "C", "text": "A, D", "correct": false}, {"label": "D", "text": "C, D", "correct": false}], "correct_answer": "B. B, C", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392860890-QTDA066006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>B, C The marked structure in the given image is gray rami communicans, as shown in the image below. Gray and White rami Communicans The neurons that do not pass through this part are those which Option B - General sensation from the skin Option C- Supply the paravertebral ganglion like coeliac ganglion.</p>\n<p><strong>Highyeild:</strong></p><p>The gray rami communicantes contain postganglionic nerve fibers of the sympathetic nervous system and are composed of largely unmyelinated neurons. This contrasts the white rami communicantes, in which heavily myelinated neurons give the rami their white appearance.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option: A, C Option: A, D Option: C, D General sensation from the viscera and General supply to the glands pass through gray rami communicans, therefore, Options A, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The gray communicating branch of the spinal nerve (gray ramus communicans) is a neuronal structure that connects the autonomic sympathetic trunk with the anterior ramus of a spinal nerve and allows for the passage of postganglionic sympathetic neurons.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During sympathetic nerve supply, the preganglionic fiber can behave in various ways and can synapse in various ways. Which of the following statements does not represent the behavior of preganglionic fiber with respect to synapse?", "options": [{"label": "A", "text": "They traverse the nearest ganglion or ascend or descend in a sympathetic chain to end in another ganglion.", "correct": false}, {"label": "B", "text": "Emerge in one of the medially directed branches of the sympathetic trunk to synapse in the ganglia of autonomic plexuses like coeliac and mesenteric plexus.", "correct": false}, {"label": "C", "text": "One preganglionic fiber synapse only with one postganglionic fiber.", "correct": true}, {"label": "D", "text": "The suprarenal gland is innervated directly by the preganglionic nerve fibers.", "correct": false}], "correct_answer": "C. One preganglionic fiber synapse only with one postganglionic fiber.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>One preganglionic fiber synapse only with one postganglionic fiber. The preganglionic sympathetic fibers originate from the cell bodies in the lateral horn. On reaching the sympathetic trunk, the preganglionic fibers behave in one of several ways: They traverse the nearest ganglion or ascend or descend in a sympathetic chain to end in another ganglion. Emerge in one of the medially directed branches of the sympathetic trunk to synapse in the ganglia of autonomic plexuses like coeliac and mesenteric plexus. The suprarenal gland is innervated directly by the preganglionic nerve fibers. Hence Option C is the correct answer.</p>\n<p><strong>Highyeild:</strong></p><p>Gray ramus communicans The grey rami communicantes exist at every level of the spinal cord. They are responsible for carrying postganglionic nerve fibers from the paravertebral ganglia to their destination and for carrying those preganglionic nerve fibers which enter the paravertebral ganglia but do not synapse.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. They traverse the nearest ganglion or ascend or descend in a sympathetic chain to end in another ganglion. Option: B. Emerge in one of the medially directed branches of the sympathetic trunk to synapse in the ganglia of autonomic plexuses like coeliac and mesenteric plexus. Option: D. The suprarenal gland is innervated directly by the preganglionic nerve fibers. Options A, B, and D statements represent the behavior of preganglionic fiber with respect to the synapse, so they are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>White ramus communicans The white rami communicantes exist only at the spinal cord levels where the intermediolateral cell column is present (T1-L2). They are responsible for carrying preganglionic nerve fibers from the spinal cord to the paravertebral ganglia.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Retraction of the protruded mandible is done by:", "options": [{"label": "A", "text": "Medial Pterygoid", "correct": false}, {"label": "B", "text": "Lateral pterygoid", "correct": false}, {"label": "C", "text": "Masseter", "correct": false}, {"label": "D", "text": "Temporalis", "correct": true}], "correct_answer": "D. Temporalis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Temporalis The temporalis muscle causes elevation and retraction of the mandible.</p>\n<p><strong>Highyeild:</strong></p><p>Origin and insertion of the temporalis muscle</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Medial Pterygoid The medial pterygoid muscle has functions including elevating the mandible (closing the mouth), protruding the mandible, mastication (especially when the maxillary teeth and the mandibular teeth are close together), and excursing the mandible (contralateral excursion occurs unilateral contraction) Option:B. Lateral pterygoid The lateral pterygoid muscle depresses the mandible and opens the mouth when assisted by the anterior belly of the digastric muscle and the mylohyoid muscle Option:C. Masseter The masseter muscle is one of the four muscles responsible for the action of mastication (chewing). When the masseter contracts it causes powerful elevation of the mandible causing the mouth to close.</p>\n<p><strong>Extraedge:</strong></p><p>PTERYGOID PLEXUS OF VEINS It lies around and within the lateral pterygoid muscle. The tributaries of the plexus correspond to the branches of the maxillary artery. The plexus is drained by the maxillary vein which begins at the posterior end of the plexus and unites with the superficial temporal vein to form the retromandibular vein. Thus, the maxillary vein accompanies only the first part of the maxillary artery. The plexus communicates: a. With the inferior ophthalmic vein through the inferior orbital fissure. b. With the cavernous sinus through the emissary’s veins. c. With the facial vein (FV) through the deep facial vein. The facial vein communicates with inferior ophthalmic veins. Thus infection from FV/inferior ophthalmic vein can reach the cavernous sinus causing its thrombosis and palsy of cranial nerves in the sinus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not a depressor of the mandible?", "options": [{"label": "A", "text": "Hyoglossus", "correct": true}, {"label": "B", "text": "Digastric", "correct": false}, {"label": "C", "text": "Geniohyoid", "correct": false}, {"label": "D", "text": "Mylohyoid", "correct": false}], "correct_answer": "A. Hyoglossus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Hyoglossus The mandible is depressed by gravity (prime mover), lateral pterygoid muscle, and suprahyoid muscles (digastrics, geniohyoid, mylohyoid). Hyoglossus is not a depressor, it’s a depressor for the tongue.</p>\n<p><strong>Highyeild:</strong></p><p>Explanation for incorrect options:- B. Digastric C. Geniohyoid D. Mylohyoid The mandible is depressed by gravity (prime mover), lateral pterygoid muscle, and suprahyoid muscles (digastrics, geniohyoid, mylohyoid). Depression of the mandible is brought about mainly by the lateral pterygoid. The digastric, geniohyoid, and mylohyoid muscles help when the mouth is opened wide or against resistance. The origin of only the lateral pterygoid is anterior, slightly lower, and medial to its insertion. During contraction, it rotates the head of the mandible and opens the mouth. During the wide opening, it pulls the articular disc forwards. So, movement occurs in both compartments. It is also done passively by gravity.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The following ligaments are present in the temporomandibular joint, except:", "options": [{"label": "A", "text": "Lateral temporomandibular ligament", "correct": false}, {"label": "B", "text": "Sphenomandibular ligament", "correct": false}, {"label": "C", "text": "Stylomandibular ligament", "correct": false}, {"label": "D", "text": "Alar ligament", "correct": true}], "correct_answer": "D. Alar ligament", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Alar ligament The alar ligament is the ligament of the 2nd cervical vertebra The alar ligaments are fibrous cords that attach to the dens bilaterally and insert into the base of the skull. They function to limit axial rotation and lateral bending on the contralateral side, and flexion secondarily.</p>\n<p><strong>Highyeild:</strong></p><p>Ligaments of TM Joint Major: Lateral temporomandibular ligament (the thickened lateral portion of the capsule, strengthens TMJ laterally) Minor: Stylomandibular ligament, sphenomandibular ligament. Ligaments of TM Joint</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Lateral temporomandibular ligament The lateral temporomandibula r ligament reinforces and strengthens the lateral part of the capsular ligament. Its fibers are directed downwards and backward. It is attached above to the articular tubercle, and below to the posterolateral aspect of the neck of the mandible. Option:B. Sphenomandibular ligament The sphenomandibular ligament is an accessory ligament that lies on a deep plane away from the fibrous capsule. It is attached superiorly to the spine of the sphenoid, and inferiorly to the lingula of the mandibular foramen. It is a remnant of the dorsal part of Meckel’s cartilage. Option:C. Stylomandibular ligament The stylomandibular ligament is another accessory ligament of the joint. It represents a thickened part of the deep cervical fascia which separates the parotid and submandibular salivary glands. It is attached above to the lateral surface of the styloid process, and below to the angle and adjacent part of the posterior border of the ramus of the mandible.</p>\n<p><strong>Extraedge:</strong></p><p>Nerve supply of TM joint Auriculotemporal nerve: Its articular twigs enter the joint from its posterior aspect. Masseteric nerve: Its articular twigs enter the joint from its anterior aspect.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Correct for the Image:", "options": [{"label": "A", "text": "Le Fort fracture 1", "correct": false}, {"label": "B", "text": "Le Fort fracture 2", "correct": false}, {"label": "C", "text": "Le Fort fracture 3", "correct": true}, {"label": "D", "text": "None", "correct": false}], "correct_answer": "C. Le Fort fracture 3", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1683681600375-QTDA033004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Le Fort fracture 3 Le Fort Classification I: horizontal detachment of maxilla along the nasal floor II: pyramidal fracture of the maxilla, including nasal bones, antra, infraorbital rims, orbital floors III: pyramidal fractures as in II, with both zygomatic bones; may be accompanied by airway problems, nasolacrimal obstruction, and CSF leakage.</p>\n<p><strong>Highyeild:</strong></p><p>Le Fort Fractures The term LeFort fractures is applied to transverse fractures of the midface. Rene LeFort described three transverse weak lines through the midfacial skeleton as a result of his cadaver studies in 1901. Le Fort Fractures I: horizontal detachment of maxilla along the nasal floor II: pyramidal fracture of the maxilla, including nasal bones, antra, infraorbital rims, orbital floors III: pyramidal fractures as in II, with both zygomatic bones; may be accompanied by airway problems, nasolacrimal obstruction, and CSF leakage</p>\n<p><strong>Extraedge:</strong></p><p>Le Fort II fractures (pyramidal fracture) Le Fort II fractures are pyramidal fractures involving the maxillary bones. From the nasal bridge, the fracture enters the medial wall of the orbit to involve the lacrimal bone and then crosses the inferior orbital rim, usually at the junction of the medial one-third and lateral two-thirds, and often involves the infraorbital foramen. The fracture line then runs beneath the zygomaticomaxillary suture, traversing the lateral wall of the maxillary sinus to extend posteriorly and horizontally across the pterygoid plates. The zygomatic bones and arches remain attached to the skull.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Protrusion of the tongue is done by:", "options": [{"label": "A", "text": "Hyoglossus", "correct": false}, {"label": "B", "text": "Styloglossus", "correct": false}, {"label": "C", "text": "Genioglossus", "correct": true}, {"label": "D", "text": "Palatoglossus", "correct": false}], "correct_answer": "C. Genioglossus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Genioglossus The primary function of the genioglossus muscle is to protrude the tongue anteriorly and deviate the tongue to the opposite side . It also aids in swallowing as it will create a passage to the GIT. When the left and right genioglossus muscles act together, they will depress the middle part of the tongue.</p>\n<p><strong>Highyeild:</strong></p><p>Actions of Tongue muscles Intrinsic muscles Actions 1. Superior longitudinal Shortens the tongue, makes its dorsum concave 2. Inferior longitudinal Shortens the tongue, makes its dorsum convex 3. Transverse Makes the tongue narrow and elongated 4. Vertical Makes the tongue broad and flattened Extrinsic muscles Actions 1. Genioglossus Protrudes the tongue 2. Hyoglossus Depresses the tongue 3. Styloglossus Retracts the tongue 4. Palatoglossus Elevates the tongue</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options:- Option:A. Hyoglossus The hyoglossus acts to both depress and retract the tongue. Option:B. Styloglossus The styloglossus muscle acts to lift the lateral edges and retract the tongue. Option:D. Palatoglossus The palatoglossus muscle functions to elevate the posterior portion of the tongue. It also draws the soft palate inferiorly, thereby narrowing the diameter of the oropharyngeal isthmus.</p>\n<p><strong>Extraedge:</strong></p><p>The chondroglossus muscle is a muscle of the tongue. It arises from the medial side of the lesser horn of the hyoid bone, before blending with intrinsic muscles of the tongue. It is supplied by the hypoglossal nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 15 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Patients with lesions of the amygdala display impairment in enhanced perception of emotionally salient events. Which of the following is a major output pathway from the amygdala?", "options": [{"label": "A", "text": "Fasciculus Arcuatus", "correct": false}, {"label": "B", "text": "Fasciculus cuneatus", "correct": false}, {"label": "C", "text": "Fasciculus of Vicq d’Azyr", "correct": false}, {"label": "D", "text": "Stria terminalis", "correct": true}], "correct_answer": "D. Stria terminalis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Stria terminalis The stria terminalis or fasciculus of Foville is one of the major output pathways from the amygdala to the septal, hypothalamic, and thalamic nuclei. Another main amygdaloid output pathway is the ventral amygdalofugal pathway.</p>\n<p><strong>Highyeild:</strong></p><p>The Stria terminalis emerges from the posterior aspect of the amygdaloid nucleus and runs as a bundle of nerve fibers posteriorly in the roof of the inferior horn of the lateral ventricle on the medial side of the tail of the caudate nucleus. It follows the curve of the caudate nucleus and lies on the floor of the body of the lateral ventricle.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The fasciculus arcuatus (choice A) or superior longitudinal fasciculus is a bundle of fibers in the cerebrum connecting ipsilateral regions of the frontal, temporal, parietal, and occipital lobes. Option: B. The fasciculus cuneatus (choice B) carries ascending sensory fibers in the dorsal funiculus of the spinal cord and terminates in the nucleus cuneatus of the medulla oblongata. Option: C. The fasciculus of Vicq d’Azyr (choice C) or mamillothalamic tract connects the mammillary bodies to the anterior nuclei of the thalamus. This bundle of fibers forms part of the Papez circuit, also involved in emotional processing. Another part of the Papez circuit is the fornix, a large efferent pathway from the hippocampus</p>\n<p><strong>Extraedge:</strong></p><p>The mammillothalamic tract provides essential connections between the mammillary body and the anterior nuclear group of the thalamus.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "True about the hypothalamus:", "options": [{"label": "A", "text": "The hypothalamus does not influence the activities of the autonomic and endocrine systems.", "correct": false}, {"label": "B", "text": "It receives few afferent visceral and somatic sensory fibers.", "correct": false}, {"label": "C", "text": "It gives off efferent fibers that pass to the sympathetic and parasympathetic outflows in the brain and spinal cord.", "correct": true}, {"label": "D", "text": "It does not assist In the regulation of water metabolism", "correct": false}], "correct_answer": "C. It gives off efferent fibers that pass to the sympathetic and parasympathetic outflows in the brain and spinal cord.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>It gives off efferent fibers that pass to the sympathetic and parasympathetic outflows in the brain and spinal cord. The hypothalamus gives off efferent fibers that pass to the sympathetic and parasympathetic outflows in the brain and spinal cord.</p>\n<p><strong>Highyeild:</strong></p><p>The hypothalamus regulates certain metabolic processes and other activities of the autonomic nervous system. It synthesizes and secretes certain neurohormones, called releasing hormones or hypothalamic hormones, which, in turn, stimulate or inhibit the secretion of hormones from the pituitary gland. The hypothalamus controls body temperature, hunger, important aspects of parenting and maternal attachment behaviors, thirst, fatigue, sleep, and circadian rhythms.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The hypothalamus influences the activities of the autonomic and endocrine systems. Option: B. The hypothalamus receives many afferent visceral and somatic sensory nerve fibers. Option: D. The hypothalamus assists in the regulation of water metabolism. The hypothalamus plays a role in controlling emotional states.</p>\n<p><strong>Extraedge:</strong></p><p>The hypothalamus is a part of the brain that contains several small nuclei with various functions. One of the most important functions is to link the nervous system to the endocrine system via the pituitary gland. The hypothalamus is located below the thalamus and is part of the limbic system. In the terminology of neuroanatomy, it forms the ventral part of the diencephalon. All vertebrate brains contain a hypothalamus. In humans, it is the size of an almond.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Sensations from the thoracic and abdominal organs are usually difficult to localize. They are conveyed by general visceral afferent (GVA) fibers, which synapse in?", "options": [{"label": "A", "text": "Ambiguus Nucleus", "correct": false}, {"label": "B", "text": "Dorsal motor nucleus of the vagus", "correct": false}, {"label": "C", "text": "Hypoglossal nucleus", "correct": false}, {"label": "D", "text": "Solitary nucleus", "correct": true}], "correct_answer": "D. Solitary nucleus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Solitary nucleus GVA fibers from the thoracic and abdominal organs have cell bodies in the inferior vagal (nodose) ganglion and project to the solitary nucleus.</p>\n<p><strong>Highyeild:</strong></p><p>Functional Components of Each Cranial Nerve Component Function Letter Symbols Afferent Fibers Sensory General somatic afferent General sensations GSA Special somatic afferent Hearing, balance, vision SSA General visceral afferent Viscera GVA Special visceral afferent Smell, taste SVA Efferent Fibers General somatic efferent Somatic striated muscles GSE General visceral efferent Glands and smooth muscles (parasympathetic innervation) GVE Special visceral efferent Branchial arch striated muscles SVE</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A . The ambiguus nucleus (choice A) provides branchial efferent (motor) fibers to the stylopharyngeus, soft palate, pharyngeal, and laryngeal muscles. Option: B. The dorsal motor nucleus of the vagus (choice B) sends parasympathetic preganglionic fibers to the thoracic and abdominal viscera. Option: C. The hypoglossal nucleus (choice C) provides motor innervation for the tongue muscles. The spinal (descending) trigeminal nucleus receives pain and temperature fibers from the face area.</p>\n<p><strong>Extraedge:</strong></p><p>Cranial Nerves Number Name Components Function Opening in Skull I Olfactory Sensory (SVA) Smell Openings in cribriform plate of ethmoid II Optic Sensory (SSA) Vision Optic canal III Oculomotor Motor (GSE, GVE) Raises upper eyelid, turns eyeball upward, downward, and medially; constricts pupil; accommodates eye Superior orbital fissure. IV Trochlear Motor (GSE) Assists in turning eyeball downward and laterally Superior orbital fissure V Trigeminal Ophthalmic division Sensory (GSA) Cornea, skin of forehead, scalp, eyelids, and nose; also mucous membrane of paranasal sinuses and nasal cavity Superior orbital fissure. Maxillary division Sensory (GSA) Skin of face over maxilla; teeth of upper jaw; mucous membrane of nose, the maxillary sinus, and palate Foramen rotundum Mandibular division Motor (SVE) Muscles of mastication, mylohyoid, anterior belly of digastric, tensor veli palatini, and tensor tympani Foramen ovale Sensory (GSA) Skin of cheek, skin over mandible and side of head, teeth of lower jaw and temporomandibular joint; mucous membrane of mouth and anterior part of tongue VI Abducent Motor (GSE) Lateral rectus muscle turns eyeball laterally Superior orbital fissure VII Facial Motor (SVE) Muscles of face and scalp, stapedius muscle, posterior belly of digastric, and stylohyoid muscles Internal acoustic meatus, facial canal, stylomastoid foramen Sensory (SVA) Taste from anterior two-thirds of tongue, from floor of mouth and palate Secretomotor (GVE) parasympathetic Submandibular and sublingual salivary glands, the lacrimal gland, and glands of nose and palate VIII Vestibulocochlear Vestibular Sensory (SSA) From utricle and saccule and semicircular canals position and movement of head Internal acoustic meatus Cochlear Sensory (SSA) Organ of Corti-hearing IX Glossopharyngeal Motor (SVE) Stylopharyngeus muscle-assists swallowing Jugular foramen Secretomotor (GVE) parasympathetic Parotid salivary gland Sensory (GVA, SVA, GSA) General sensation and taste from posterior third of tongue and pharynx; carotid sinus (baroreceptor); and carotid body (chemoreceptor) X Vagus Motor (GVE, SVE) Sensory (GVA, SVA, GSA) Heart and great thoracic blood vessels; larynx, trachea, bronchi, and lungs; alimentary tract from pharynx to splenic flexure of colon; liver, kidneys, and pancreas Jugular foramen XI Accessory Cranial root Motor (SVE) Muscles of soft palate (except tensor veli palatini), pharynx (except stylopharyngeus), and larynx (except cricothyroid) in branches of vagus Jugular foramen Spinal root Motor (SVE) Sternocleidomastoid and trapezius muscles XII Hypoglossal Motor (GSE) Muscles of tongue (except palatoglossus) controlling its shape and movement Hypoglossal canal</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is not a part of the epithalamus?", "options": [{"label": "A", "text": "Pineal Body", "correct": false}, {"label": "B", "text": "Posterior commissure", "correct": false}, {"label": "C", "text": "Trigonum habenula", "correct": false}, {"label": "D", "text": "Geniculate body", "correct": true}], "correct_answer": "D. Geniculate body", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Geniculate body Geniculate bodies are located in the posteroventral region of the thalamic nuclei, immediately abutting the pulvinar and posterior to the inferior choroidal point of the choroid plexus.</p>\n<p><strong>Highyeild:</strong></p><p>The epithalamus occupies the caudal part of the roof of the diencephalon and consists of: The right and left habenular nuclei, each situated beneath the floor of the corresponding habenular trigone. The pineal body or epiphysis cerebri. The habenular commissure lies superior to suprapineal recess. The posterior commissure lies inferior to the suprapineal recess. Components of the epithalamus</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Pineal Body Option: B. Posterior commissure Option: C. Trigonum habenula Options A, B, and C are the contents of the epithalamus.</p>\n<p><strong>Extraedge:</strong></p><p>Thalamic Nuclei: Connections and Functions Thalamic Nucleus Afferent Neuronal Loop Efferent Neuronal Loop Function Anterior Mammillothalamic tract, cingulate gyrus, hypothalamus Cingulate gyrus, hypothalamus Emotional tone, mechanisms of recent memory Dorsomedial Prefrontal cortex, hypothalamus, other thalamic nuclei Prefrontal cortex, hypothalamus, other thalamic nuclei Integration of somatic, visceral, and olfactory information and relation to emotional feelings and subjective states Lateral dorsal, lateral posterior, pulvinar Cerebral cortex, other thalamic nuclei Cerebral cortex, other thalamic nuclei Unknown Ventral anterior Reticular formation, substantia nigra, corpus striatum, premotor cortex, other thalamic nuclei Reticular formation, substantia nigra, corpus striatum, premotor cortex, other thalamic nuclei Influences activity of motor cortex Ventral lateral As in ventral anterior nucleus but also major input from cerebellum and minor input from red nucleus Influences motor activity of motor cortex Ventral posteromedial (VPM) Trigeminal lemniscus, gustatory fibers Primary somatic sensory (areas 3, 1, and 2) cortex Relays common sensations to consciousness Ventral posterolateral (VPL) Medial and spinal lemnisci Primary somatic sensory (areas 3, 1, and 2) cortex Relays common sensations to consciousness Intralaminar Reticular formation, spinothalamic and trigeminothalamic tracts To cerebral cortex via other thalamic nuclei, corpus striatum Influences levels of consciousness and alertness Midline Reticular formation Unknown Unknown Reticular Cerebral cortex, reticular formation Other thalamic nuclei Cerebral cortex regulates thalamus Medial geniculate body Inferior colliculus, lateral lemniscus from both ears but predominantly the contralateral ear Auditory radiation to superior temporal gyrus Hearing Lateral geniculate body Optic tract Optic radiation to visual cortex of occipital lobe Visual information from opposite field of vision</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following is projected to the ventral posterior nucleus of the thalamus?", "options": [{"label": "A", "text": "Lateral Lemniscus", "correct": false}, {"label": "B", "text": "Medial lemniscus", "correct": true}, {"label": "C", "text": "Corticospinal tract", "correct": false}, {"label": "D", "text": "Subthalamic fasciculus", "correct": false}], "correct_answer": "B. Medial lemniscus", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Medial lemniscus The ventral posterior nucleus receives neural input from the medial lemniscus, spinothalamic tracts, and trigeminothalamic tract. It projects to the somatosensory cortex and the ascending reticular activating system.</p>\n<p><strong>Highyeild:</strong></p><p>The ventral posterior nucleus is divided into: Ventral posterolateral nucleus, which receives sensory information from the body. The ventral posteromedial nucleus receives sensory information from the head and face via the trigeminal nerve. Ventral intermediate nucleus, implicated in oscillatory tremor generation in Parkinson's disease and essential tremor.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. Lateral Lemniscus Option:C. Corticospinal tract Option:D. Subthalamic fasciculus The ventral posterior nucleus receives neural input from the medial lemniscus. Therefore, Options A, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Thalamic Nuclei: Connections and Functions Thalamic Nucleus Afferent Neuronal Loop Efferent Neuronal Loop Function Anterior Mammillothalamic tract, cingulate gyrus, hypothalamus Cingulate gyrus, hypothalamus Emotional tone, mechanisms of recent memory Dorsomedial Prefrontal cortex, hypothalamus, other thalamic nuclei Prefrontal cortex, hypothalamus, other thalamic nuclei Integration of somatic, visceral, and olfactory information and relation to emotional feelings and subjective states Lateral dorsal, lateral posterior, pulvinar Cerebral cortex, other thalamic nuclei Cerebral cortex, other thalamic nuclei Unknown Ventral anterior Reticular formation, substantia nigra, corpus striatum, premotor cortex, other thalamic nuclei Reticular formation, substantia nigra, corpus striatum, premotor cortex, other thalamic nuclei Influences activity of motor cortex Ventral lateral As in ventral anterior nucleus but also major input from cerebellum and minor input from red nucleus Influences motor activity of motor cortex Ventral posteromedial (VPM) Trigeminal lemniscus, gustatory fibers Primary somatic sensory (areas 3, 1, and 2) cortex Relays common sensations to consciousness Ventral posterolateral (VPL) Medial and spinal lemnisci Primary somatic sensory (areas 3, 1, and 2) cortex Relays common sensations to consciousness Intralaminar Reticular formation, spinothalamic and trigeminothalamic tracts To cerebral cortex via other thalamic nuclei, corpus striatum Influences levels of consciousness and alertness Midline Reticular formation Unknown Unknown Reticular Cerebral cortex, reticular formation Other thalamic nuclei Cerebral cortex regulates thalamus Medial geniculate body Inferior colliculus, lateral lemniscus from both ears but predominantly the contralateral ear Auditory radiation to superior temporal gyrus Hearing Lateral geniculate body Optic tract Optic radiation to visual cortex of occipital lobe Visual information from opposite field of vision</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "All the following pairs are correct for nuclei of the hypothalamus, except:", "options": [{"label": "A", "text": "Ventro-Medial: Hunger", "correct": true}, {"label": "B", "text": "Supraoptic: Water conservation", "correct": false}, {"label": "C", "text": "Posterior nucleus: Shivering center", "correct": false}, {"label": "D", "text": "Supra-chiasmatic: Circadian rhythm", "correct": false}], "correct_answer": "A. Ventro-Medial: Hunger", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ventro-Medial: Hunger The ventro-medial nucleus is the center for satiety (not hunger).</p>\n<p><strong>Highyeild:</strong></p><p>Main Hypothalamic Afferent and Efferent Nervous Connections Pathway Origin Destination Afferent Medial and spinal lemnisci, tractus solitarius, reticular formation Viscera and somatic structures Hypothalamic nuclei Visual fibers Retina Suprachiasmatic nucleus Medial forebrain bundle Olfactory mucous membrane Hypothalamic nuclei Auditory fibers Inner ear Hypothalamic nuclei Corticohypothalamic fibers Frontal lobe of cerebral cortex Hypothalamic nuclei Hippocampohypothalamic fibers; possibly main output pathway of limbic system Hippocampus Nuclei of mammillary body Amygdalohypothalamic fibers Amygdaloid complex Hypothalamic nuclei Thalamohypothalamic fibers Dorsomedial and midline nuclei of thalamus Hypothalamic nuclei Tegmental fibers Tegmentum of midbrain Hypothalamic nuclei Efferent Descending fibers in reticular formation to brainstem and spinal cord Preoptic, anterior, posterior, and lateral nuclei of hypothalamus Craniosacral parasympathetic and thoracolumbar sympathetic outflows Mammillothalamic tract Nuclei of mammillary body Anterior nucleus of thalamus; relayed to cingulate gyrus Mammillotegmental tract Nuclei of mammillary body Reticular formation in tegmentum of midbrain Multiple pathways Hypothalamic nuclei Limbic system</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:B . Supraoptic: Water conservation The anterior hypothalamus has osmoreceptors, and centers like the supra-optic nucleus secrete vasopressin (ADH) for water conservation. Option:C. Posterior nucleus: Shivering center The posterior nucleus works for heat conservation (shivering center). Option:D. Supra-chiasmatic: Circadian rhythm Supra-chiasmatic regulates the circulation rhythm.</p>\n<p><strong>Extraedge:</strong></p><p>Hypothalamic-Releasing and Inhibitory Hormones and Their Effects on Hypophysis (Pituitary) Anterior Lobe Hypothalamic Regulatory Hormone Anterior Pituitary Hormone Functional Result Growth hormone-releasing hormone (GHRH) Growth hormone (GH) Stimulates linear growth in epiphyseal cartilages Growth hormone-inhibiting hormone (GHIH) or somatostatin Growth hormone (reduced production) Reduces linear growth in epiphyseal cartilages Prolactin-releasing hormone (PRH) Prolactin (luteotropic hormone, LTH) Stimulates lactogenesis Prolactin-inhibiting hormone (PIH), dopamine Prolactin (luteotropic hormone, LTH) (reduced production) Reduces lactogenesis Corticotropin-releasing hormone (CRH) Adrenocorticotropic hormone (ACTH) Stimulates adrenal gland to produce corticosteroids and sex hormones Thyrotropin-releasing hormone (TRH) Thyroid-stimulating hormone (TSH) Stimulates thyroid gland to produce thyroxine Luteinizing hormone-releasing hormone (LHRH) Luteinizing hormone (LH) and follicle- stimulating hormone (FSH) Stimulates ovarian follicles and production of estrogen and progesterone</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Thoracic duct does NOT drain?", "options": [{"label": "A", "text": "The right upper part of the body", "correct": true}, {"label": "B", "text": "Left upper part of the body", "correct": false}, {"label": "C", "text": "The right lower part of the body", "correct": false}, {"label": "D", "text": "Left lower part of the body", "correct": false}], "correct_answer": "A. The right upper part of the body", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The right upper part of the body The right upper quadrant of the body drains the lymphatics into the right lymphatic duct and the rest of the body drains into the thoracic duct. Diagram showing parts of the body that drain into the right lymphatic duct.</p>\n<p><strong>Highyeild:</strong></p><p>The right lymphatic duct is an important lymphatic vessel that drains the right upper quadrant of the body. It forms various combinations with the right subclavian vein and right internal jugular vein. The right lymphatic duct courses along the medial border of the anterior scalene at the root of the neck. The right lymphatic duct forms various combinations with the right subclavian vein and right internal jugular vein. It is approximately 1.25 cm long.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Left upper part of the body Option C. Right lower part of the body Option D. Left lower part of the body Areas mentioned in Options B, C, and D all drain into the thoracic duct.</p>\n<p><strong>Extraedge:</strong></p><p>The right d uct drains lymph fluid from: the upper right section of the trunk, (right thoracic cavity, via the right bronchomediastinal box), the right arm (via the right subclavian trunk ), and right side of the head and neck (via the right jugular box), also, in some individuals, the lower lobe of the left lung. All other sections of the human body are drained by the thoracic duct.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 39-year-old woman came to OPD complaining of an inability to reach a pantry shelf just above her head. History reveals that 2 months ago she underwent a mastectomy procedure and she did not have this complaint prbeforehe surgery. Which nerve was most likely damaged during surgery to result in the patient’s complaint?", "options": [{"label": "A", "text": "Axillary", "correct": false}, {"label": "B", "text": "Spinal accessory", "correct": false}, {"label": "C", "text": "Long thoracic", "correct": true}, {"label": "D", "text": "Radial", "correct": false}], "correct_answer": "C. Long thoracic", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Long thoracic During mastectomy procedures, three superficial nerves are susceptible to ligation or laceration: the long thoracic nerve, the intercostobrachial nerve, and the thoracodorsal nerve . In the event of injury to the long thoracic nerve, the patient complains of an inability to fully abduct the humerus above the horizontal .</p>\n<p><strong>Highyeild:</strong></p><p>Serratus anterior (supplied by the long thoracic nerve) is necessary to elevate, rotate, and abduct the scapula, to facilitate abduction of the humerus above the shoulder. Because the patient does not indicate any loss of medial rotation or adduction of the humerus, ligation or injury of the thoracodorsal nerve can be eliminated.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Axillary Axillary nerve damage can lead to a loss of shoulder abduction due to paralysis of the deltoid muscle or loss of sensation in the shoulder. Conditions associated with axillary nerve dysfunction include fracture of the humerus (upper arm bone), pressure from casts or splints, and improper use of crutches. Option B . Spinal accessory The spinal accessory nerve is located in the posterior triangle of the neck and is injured in case of surgical interventions involving this area. Spinal accessory nerve injury leads to paralysis of the sternocleidomastoid and trapezius muscles. Trapezius muscle denervation can lead to loss of overhead abduction of shoulders. O ption D. Radial Radial nerve injury leads to a \"wrist dr” If damaged at the axilla, there will be a loss of extension of the forearm, hand, and fingers. Thus, this usually presents with a wrist drop on physical examination. There will be a sensory loss in the lateral arm.</p>\n<p><strong>Extraedge:</strong></p><p>Anterior shoulder dislocation is the most common occurring dislocation at the shoulder, which can cause direct trauma (compression or traction) to the axillary nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient brought to OPD presenting with a history of paragliding suddenly got stuck in a tree and suffered an injury to the spine because of which he got a high spinal injury. Which among the following muscles prevent paradoxical motion of the diaphragm even in high spinal injury?", "options": [{"label": "A", "text": "Intercostal Muscle", "correct": true}, {"label": "B", "text": "Subcostalis muscles", "correct": false}, {"label": "C", "text": "Transverse thoracic", "correct": false}, {"label": "D", "text": "Levator costarum", "correct": false}], "correct_answer": "A. Intercostal Muscle", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Intercostal Muscle Intercostal muscle -The primary role of the intercostal muscles is to stiffen the chest wall, preventing paradoxical motion during inspiratory diaphragmatic descent . This becomes most obvious immediately after high spinal injury when there is flaccid paralysis of the entire trunk and only the diaphragm remains functional.</p>\n<p><strong>Highyeild:</strong></p><p>Intercostal muscles are many different groups of muscles that run between the ribs and help form and move the chest wall. The intercostal muscles are mainly involved in the mechanical aspect of breathing by helping expand and shrink the size of the chest cavity. Intercostal muscles</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B . Subcostalis muscles The Subcostalis muscl e consists of muscular and aponeurotic fasciculi, which are usually well-developed only in the lower part of the thorax. The Subcostalis muscle originates from the inner surface of one rib and is inserted into the inner surface of the second or third rib below, near its angle. Their fibers run in the same direction as those of the Intercostales interni. Depresses the ribs to assist in expiration. Option C. Transverse thoracic The Transversus thoracic muscle, also known as triangular sterni , lies internal to the thoracic cage, anteriorly. It is usually a thin plane of muscular and tendinous fibers, situated upon the inner surface of the front wall of the chest. It is in the same layer as the subcostal and innermost intercostal muscles. It depresses the ribs. Contraction of this muscle aids in exertional expiration by decreasing the transverse diameter of the thoracic cage. Option D. Levator costarum The Levatores costarum, twelve in number on either side, are small tendinous and fleshy bundles, which arise from the ends of the transverse processes of the seventh cervical and upper eleven thoracic vertebrae. Assists in elevation of the thoracic rib cage</p>\n<p><strong>Extraedge:</strong></p><p>There are three principal layers of Intercostal muscles: External intercostal muscles also known as intercostalis externus aid in quiet and forced inhalation. Internal intercostal muscles also known as intercostalis internus aid in forced expiration (quiet expiration is a passive process). Innermost intercostal muscles also known as intercostalis intimus are deep layers of the internal intercostal muscles which are separated from them by a neurovascular bundle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A patient came to you with a complaint of, getting a strain in the chest region while playing cricket, which is causing discomfort. One of the muscles which elevate the ribs causes the strain which among the following muscles causes this strain?", "options": [{"label": "A", "text": "Serratus Posterior Superior", "correct": true}, {"label": "B", "text": "Subcoastalis", "correct": false}, {"label": "C", "text": "Transverse thoracic", "correct": false}, {"label": "D", "text": "Serratous posterior inferior", "correct": false}], "correct_answer": "A. Serratus Posterior Superior", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Serratus Posterior Superior The serratus posterior superior muscle is a thin, quadrilateral muscle. It is situated at the upper back part of the thorax, deep into the rhomboid muscles. Serratus posterior superior muscle elevates the second to fifth ribs. This aids deep respiration.</p>\n<p><strong>Highyeild:</strong></p><p>The serratus posterior superior muscle arises by aponeurosis from the lower part of the nuchal ligament, from the spinous processes of C7, T1, T2, and sometimes T3, and from the supraspinal ligament. It is inserted, by four fleshy digitations into the upper borders of the second, third, fourth, and fifth ribs past the angle of the rib.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Subcoastalis The Subcostalis muscle consists of muscular and aponeurotic fasciculi, which are usually well-developed only in the lower part of the thorax. The Subcostalis muscle originates from the inner surface of one rib and is inserted into the inner surface of the second or third rib below, near its angle. Their fibers run in the same direction as those of the Intercostales interni. Depresses the ribs to assist in expiration. Option C. Transverse thoracic The Transversus thoracic muscle, also known as triangular sterni , lies internal to the thoracic cage, anteriorly. It is usually a thin plane of muscular and tendinous fibers, situated upon the inner surface of the front wall of the chest. It is in the same layer as the subcostal and innermost intercostal muscles. It depresses the ribs. Contraction of this muscle aids in exertional expiration by decreasing the transverse diameter of the thoracic cage. Option D. Serratous posterior inferior Serratus posterior inferior draws the lower ribs backward and downward to assist in the rotation and extension of the trunk. This movement of the ribs may also contribute to inhalation and forced expiration of air from the lungs.</p>\n<p><strong>Extraedge:</strong></p><p>Serratus posterior inferior arises by a thin aponeurosis from the spinous processes of the lower two thoracic and upper two or three lumbar vertebrae. Passing obliquely upward and lateralward, it becomes fleshy and divides into four flat digitations. These are inserted into the inferior borders of the lower four ribs, a little beyond their angles. The thin aponeurosis of origin is intimately blended with the thoracolumbar fascia and aponeurosis of the latissimus dorsi muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were doing Cadaveric dissection, suddenly you noticed a muscle that you have not read about in your book, So you called your teacher, He said that the muscle which appears as a parasternal mass deep to the superficial fascia of the anterior thoracic wall and superficial to the pectoral fascia overlying pectoralis major. It may be a cord-like, flat band, or irregular and flame-like in shape, is almost twice as commonly unilateral, and occurs more often on the right side. What is the name of the muscle?", "options": [{"label": "A", "text": "Serratus Posterior Superior", "correct": false}, {"label": "B", "text": "Subcoastalis", "correct": false}, {"label": "C", "text": "Transverse thoracic", "correct": false}, {"label": "D", "text": "Sternalis", "correct": true}], "correct_answer": "D. Sternalis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Sternalis The Sternalis muscle appears as a parasternal mass deep to the superficial fascia of the anterior thoracic wall and superficial to the pectoral fascia overlying the pectoralis It may be a cord-like, flat band, or irregular and flame-like in shape, is almost twice as commonly unilateral, and occurs more often on the right side. Various attachment sites of the Sternalis muscle are, the sternum, inferior border of the clavicle, sternocleidomastoid fascia, pectoralis major, and the upper ribs and their costal cartilages, all superiorly, and the lower ribs and their costal cartilages, pectoralis major, the rectus sheath and the external abdominal oblique aponeurosis, all inferiorly. The muscle occurs occasionally in the general population, but there is great variation both within and between different geographic populations.</p>\n<p><strong>Highyeild:</strong></p><p>The function of the sternalis muscle It may function as a proprioceptive sensor for thoracic wall movements. It may also take part in the movement of the shoulder joint or have an additional role in the elevation of the chest wall. Sternalis Muscle</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Serratus Posterior Superior The serratus posterior superior muscle arises by aponeurosis from the lower part of the nuchal ligament, from the spinous processes of C7, T1, T2, and sometimes T3, and from the supraspinal ligament. It is inserted, by four fleshy digitations into the upper borders of the second, third, fourth, and fifth ribs past the angle of the rib. Option B. Subcoastalis The Subcostalis muscle consists of muscular and aponeurotic fasciculi, which are usually well-developed only in the lower part of the thorax. The Subcostalis muscle originates from the inner surface of one rib and is inserted into the inner surface of the second or third rib below, near its angle. Their fibers run in the same direction as those of the Intercostales interni. Depresses the ribs to assist in expiration. Option C. Transverse thoracic The Transversus thoracic m uscle, also known as triangular sterni , lies internal to the thoracic cage, anteriorly. It is usually a thin plane of muscular and tendinous fibers, situated upon the inner surface of the front wall of the chest. It is in the same layer as the subcostal and innermost intercostal muscles. It depresses the ribs. Contraction of this muscle aids in exertional expiration by decreasing the transverse diameter of the thoracic cage.</p>\n<p><strong>Extraedge:</strong></p><p>The presence of the sternalis is asymptomatic but aesthetic complaints have been reported as it was reported to cause chest asymmetry or deviation of the nipple-areola complex. The presence of the sternalis may cause alterations in the electrocardiogram or confusion in mammography. However, there is a potential benefit of the muscle as it can be used as a flap in reconstructive surgery of the head and neck and the anterior chest wall.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "An athlete came to you he is a javelin thrower, and he was practicing for an upcoming match suddenly when he was practicing he started to feel pain in the back side of his chest on both the right and left center, ECG was done which was normal, other vital were also normal. That time you remember there is a muscle that arises from the tips of the transverse processes of the seventh cervical and first to the eleventh thoracic vertebrae. They pass obliquely downwards and laterally, parallel with the posterior borders of the external intercostals. Each is attached to the upper edge and external surface of the rib immediately below the vertebra from which it takes its origin, between the tubercle and the angle.", "options": [{"label": "A", "text": "Serratus Posterior Superior", "correct": false}, {"label": "B", "text": "Subcoastalis", "correct": false}, {"label": "C", "text": "Transverse thoracic", "correct": false}, {"label": "D", "text": "Levatores costarum", "correct": true}], "correct_answer": "D. Levatores costarum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Levatores costarum Levatores costarum are strong bundles, 12 on each side, which arise from the tips of the transverse processes of the seventh cervical and first to the eleventh thoracic vertebrae. They pass obliquely downwards and laterally, parallel with the posterior borders of the external intercostals. Each is attached to the upper edge and external surface of the rib immediately below the vertebra from which it takes its origin, between the tubercle and the angle (lavatories costarum breves). Each of the four lower muscles divides into two fasciculi; one is attached as already described, and the other descends to the second rib below its origin (lavatories costarum long). They have a role in forceful inspiration.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A . Serratus Posterior Superior The serratus posterior superior muscle arises by aponeurosis from the lower part of the nuchal ligament, from the spinous processes of C7, T1, T2, and sometimes T3, and from the supraspinal ligament. It is inserted, by four fleshy digitations into the upper borders of the second, third, fourth, and fifth ribs past the angle of the rib. Option B. Subcoastalis The Subcostalis muscl e consists of muscular and aponeurotic fasciculi, which are usually well-developed only in the lower part of the thorax. The Subcostalis muscle originates from the inner surface of one rib and is inserted into the inner surface of the second or third rib below, near its angle. Their fibers run in the same direction as those of the Intercostales interni. Depresses the ribs to assist in expiration. Option C. Transverse thoracic The transverse thoracic muscle, also known as triangular sterni , lies internal to the thoracic cage, anteriorly. It is usually a thin plane of muscular and tendinous fibers, situated upon the inner surface of the front wall of the chest. It is in the same layer as the subcostal and innermost intercostal muscles. It depresses the ribs. Contraction of this muscle aids in exertional expiration by decreasing the transverse diameter of the thoracic cage.</p>\n<p><strong>Extraedge:</strong></p><p>Levatores costarum origin : transverse processes of C7 to T11 vertebrae. insertion : rib immediately below. blood supply : dorsal branches of posterior intercostal arteries. innervation : dorsal rami of C8 to T11 spinal nerves. action : elevate ribs.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were attending your anatomy lecture where they are teaching about the chest muscle. Among them, one muscle's main function is to elevate the rib but it is also a rotator to its attached ribs. What is that muscle?", "options": [{"label": "A", "text": "Serrattous Posterior Superior", "correct": false}, {"label": "B", "text": "Levatores costarum", "correct": true}, {"label": "C", "text": "Transverse thoracicus", "correct": false}, {"label": "D", "text": "Serratous posterior inferior", "correct": false}], "correct_answer": "B. Levatores costarum", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Levatores costarum Levatores costarum elevate the ribs but their importance in ventilation is disputed. They are also said t o act from their costal attachments as rotators and lateral flexors of the vertebral column.</p>\n<p><strong>Highyeild:</strong></p><p>The levatores costarum (or levator costae) muscles are paired muscles of the posterior thorax. The number twelve on each side attaches to the transverse processes other than the 7 to T11 vertebrae and the ribs below, helping to elevate the ribs during respiration. Levatores costarum</p>\n<p><strong>Random:</strong></p><p>Explanation for Incorrect Options :- Option A: The attachments of serratus posterior superior indicate that it could elevate the ribs Option C: Transversus thoracis draws down the costal cartilages to which it is attached Option D: Serratus posterior inferior draws the lower ribs downwards and backward, although possibly not in ventilation.</p>\n<p><strong>Extraedge:</strong></p><p>Serratus posterior inferior muscle forms from a thin, broad aponeurosis which is attached to the spinous processes of T11 to L2 vertebrae, and the intervening supraspinous ligament. It passes superolateral and inserts onto the inferior border, just lateral to the angles of the 9th to 12th ribs. It is separated from the serratus posterior superior muscle by a wide interval.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were studying about muscles of the chest wall at that time you were imagining all the muscles and their innervation and at that moment it struck to your mind that one of your seniors told you that he was asked in viva a question about the muscle of the chest wall that is a muscle whose origin is from the spines of the seventh cervical and upper two or three thoracic vertebrae, and their supraspinous ligaments, which act as the elevator of ribs is supplied by which nerve.", "options": [{"label": "A", "text": "Lateral branches of the dorsal rami of the corresponding thoracic spinal nerves", "correct": false}, {"label": "B", "text": "Adjacent inter-costal nerves", "correct": false}, {"label": "C", "text": "Second, third, fourth, and fifth intercostal nerves", "correct": true}, {"label": "D", "text": "Ventral rami of the ninth, tenth, eleventh, FF, and twelfth thoracic spinal nerves", "correct": false}], "correct_answer": "C. Second, third, fourth, and fifth intercostal nerves", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Second, third, fourth, and fifth intercostal nerves Serratus posterior superior - origin is from the spines of the seventh cervical and upper two or three thoracic vertebrae, and their supraspinous ligaments which act as elevator of ribs. Innervated by second, third, fourth, and fifth intercostal nerves.</p>\n<p><strong>Highyeild:</strong></p><p>Serratus Posterior inferior origin : spinous processes of T11 to L2 vertebrae and supraspinous ligament insertion : inferior border of 9th to 12th ribs innervation : The serratus posterior inferior muscle receives motor supply from the ventral rami of the 9th to 12th thoracic spinal nerves (intercostal nerves) arterial supply : intercostal arteries action : depresses ribs.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A. Lateral branches of the dorsal rami of the corresponding thoracic spinal nerves lavatories costarum -rise from the tips of the transverse processes of the seventh cervical and first to eleventh thoracic vertebrae and are attached to the upper edge and external surface of the rib immediately below the vertebra from which it takes origin, between the tubercle and the angle. It elevates the ribs Levatores costarum are supplied by the lateral branches of the dorsal rami of the corresponding thoracic spinal nerves. Option B. Adjacent intercostal nerves Transverse thoracic arises from the lower third of the posterior surface of the sternum, the xiphoid process, and the costal cartilages of the lower three or four true ribs near their sternal ends. The fibers diverge and ascend laterally as slips that pass into the lower borders and inner surfaces of the costal cartilages of the second, third, fourth, fifth, and sixth ribs. The Transversus thoracic is supplied by the adjacent intercostal nerves. Action Transversus thoracic draws down the costal cartilages to which it is attached Option D. Ventral rami of the ninth, tenth, eleventh, and twelfth thoracic spinal nerves Serratus posterior inferior - It arises from the spines of the lower two thoracic and upper two or three lumbar vertebrae and their supraspinous ligaments by a thin aponeurosis that blends with the lumbar part of the thoracolumbar fascia. Serratus posterior inferior is innervated by ventral rami of the ninth, tenth, eleventh, and twelfth thoracic spinal nerves. Action Serratus posterior inferior draws the lower ribs downwards and backward, although possibly not in ventilation.</p>\n<p><strong>Extraedge:</strong></p><p>Serratus posterior superior elevates the ribs and thus supports inspiration ( accessory muscle of inspiration). In contrast, the Serratus posterior inferior helps during expiration by depressing the ribs (accessory muscle of expiration).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following muscles is not supplied by adjacent intercostal nerves", "options": [{"label": "A", "text": "Internal Intercostal", "correct": false}, {"label": "B", "text": "Subcoastalis", "correct": false}, {"label": "C", "text": "Transverse thoracic", "correct": false}, {"label": "D", "text": "Serratous posterior superior", "correct": true}], "correct_answer": "D. Serratous posterior superior", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Serratous posterior superior Serratus s posterior superior -origin is from the spines of the seventh cervical and upper two or three thoracic vertebrae, and their supraspinous ligaments which act as the elevator of ribs Innervated by second, third, fourth, and fifth intercostal nerves.</p>\n<p><strong>Highyeild:</strong></p><p>Serratus posterior superior and serratus posterior inferior, especially Serratus posterior superior may participate and cause myofascial pain syndrome and its referred pattern can be overlapped with other muscles as it lies deeper . This referred pain starts from the back of the shoulder and runs to the elbow and ulnar side of the wrist, it may also refer to the chest and inner arm. Serratus posterior inferior pain is localized and doesn't have a preferred pattern.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A: internal intercostal muscle-Eleven pairs of internal intercostals begin anteriorly at the sternum, in the interspaces between the cartilages of the true ribs, and at the anterior extremities of the cartilages of the ‘false’ ribs. Internal intercostals are supplied by the adjacent inter-costal nerves. Option B: Subcostalis consist of muscular and aponeurotic fasciculi and are usually well developed only in the lower part of the thorax. Each descends from the internal surface of one rib, near its angle, to the internal surface of the second or third rib below Subcostales are supplied by the adjacent intercostal nerves. Option C: Transverse thoracic is supplied by the adjacent intercostal nerves. Action Transversus thoracis draws down the costal cartilages to which it is attached.</p>\n<p><strong>Extraedge:</strong></p><p>Serratus posterior superior muscle due to improper posture or inappropriate use of muscle for example- holding a phone between ear and shoulder cause scapulocostal syndrome and may be misdiagnosed with the lesion of spinal nerves of the cervical spine.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You are giving a lecture to your student on the thorax while taking a class on thoracic muscle you taught them about all muscle and you kept a test for them by saying whoever get this answer right will get a gift, the question is as follows: a muscle arises from the tips of the transverse processes of the seventh cervical and first to eleventh thoracic vertebrae and attached to the upper edge and external surface of the rib immediately below the vertebra from which it takes origin, between the tubercle and the angle what is the nerve supply of that muscle?", "options": [{"label": "A", "text": "Lateral branches of the dorsal rami of the corresponding thoracic spinal nerves.", "correct": true}, {"label": "B", "text": "Adjacent intercostal nerves.", "correct": false}, {"label": "C", "text": "Second, third, fourth, and fifth intercostal nerves.", "correct": false}, {"label": "D", "text": "Ventral rami of the ninth, tenth, eleventh, and twelfth thoracic spinal nerves.", "correct": false}], "correct_answer": "A. Lateral branches of the dorsal rami of the corresponding thoracic spinal nerves.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral branches of the dorsal rami of the corresponding thoracic spinal nerves. Levatores costarum -rise from the tips of the transverse processes of the seventh cervical and first to eleventh thoracic vertebrae and are attached to the upper edge and external surface of the rib immediately below the vertebra from which it takes origin, between the tubercle and the angle. It elevates the ribs Levatores costarum are supplied by the lateral branches of the dorsal rami of the corresponding thoracic spinal nerves.</p>\n<p><strong>Highyeild:</strong></p><p>Levatores costarum elevates the ribs but their role and importance in ventilation is disputed. From their costal attachments, they may assist in rotation and lateral flexion of the vertebral column.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option B. Adjacent intercostal nerves Transverse thoracic arises from the lower third of the posterior surface of the sternum, the xiphoid process, and the costal cartilages of the lower three or four true ribs near their sternal ends. The fibers diverge and ascend laterally as slips that pass into the lower borders and inner surfaces of the costal cartilages of the second, third, fourth, fifth, and sixth ribs. The transverse thoracis is supplied by the adjacent intercostal nerves. Action Transversus thoracis draws down the costal cartilages to which it is attached. Option C. Second, third, fourth, and fifth intercostal nerves. Serratus posterior superior - origin is from the spines of the seventh cervical and upper two or three thoracic vertebrae, and their supraspinous ligaments which act as elevator of ribs. Innervated by second, third, fourth, and fifth intercostal nerves. Option D. Ventral rami of the ninth, tenth, eleventh, and twelfth thoracic spinal nerves Serratus posterior inferior - It arises from the spines of the lower two thoracic and upper two or three lumbar vertebrae and their supraspinous ligaments by a thin aponeurosis that blends with the lumbar part of the thoracolumbar fascia. Serratus posterior inferior is innervated by ventral rami of the ninth, tenth, eleventh, and twelfth thoracic spinal nerves. Action Serratus posterior inferior draws the lower ribs downwards and backward, although possibly not in ventilation.</p>\n<p><strong>Extraedge:</strong></p><p>Contraction of the intercostal muscles during inspiration and expiration varies according to the intercostal space in which they are located and the position of the muscles within that space. The intercostal muscles contribute to the rigidity of the thoracic wall, helping to maximize inspiratory and expiratory volumes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following arteries arise from the subclavian artery?", "options": [{"label": "A", "text": "Posterior Intercostal Artery", "correct": false}, {"label": "B", "text": "Musculophrenic artery", "correct": false}, {"label": "C", "text": "Internal thoracic artery", "correct": true}, {"label": "D", "text": "Superior intercostal artery", "correct": false}], "correct_answer": "C. Internal thoracic artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Internal thoracic artery The internal thoracic artery (internal mammary artery) arises inferiorly from the first part of the subclavian artery, approximately 2 cm above the sternal end of the clavicle and opposite the root of the thyrocervical trunk.</p>\n<p><strong>Highyeild:</strong></p><p>The internal thoracic artery arises from the anterior surface of the subclavian artery near its origin. It has a width of between 1-2 mm. It travels downward on the inside of the rib cage, approximately 1 cm from the sides of the sternum, and thus medial to the nippl The internal thoracic vein accompanies it. It runs deep to the abdominal external oblique muscle but is superficial to the vagus nerve.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option A: Posterior intercostal artery-There are usually nine pairs of posterior intercostal arteries. They arise from the posterior aspect of the descending thoracic aorta and are distributed to the lower nine intercostal spaces. Option B: Musculophrenic artery arises from the internal thoracic artery The musculophrenic artery passes inferolaterally behind the seventh to ninth costal cartilages, traverses the diaphragm near the ninth, and ends near the last intercostal space. Option D: Superior intercostal artery- The superior intercostal artery arises from the costocervical trunk. It descends between the pleura and the necks of the first and second ribs and anastomoses with the third posterior intercostal artery.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following is the relation of the internal thoracic artery as it enters the thorax?", "options": [{"label": "A", "text": "Pectoralis major, the first six costal cartilages, external intercostal membranes, internal intercostals, and terminations of the upper six intercostal nerves.", "correct": false}, {"label": "B", "text": "The artery is accompanied by a chain of lymph nodes and by venae comitantes.", "correct": false}, {"label": "C", "text": "Phrenic nerve", "correct": true}, {"label": "D", "text": "Sternal end of the clavicle, the internal jugular and brachio- cephalic veins, and the first costal cartilage", "correct": false}], "correct_answer": "C. Phrenic nerve", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Phrenic nerve The internal thoracic artery enters the thorax, the phrenic nerve crosses it obliquely from its lateral side, either superiorly or inferiorly.</p>\n<p><strong>Highyeild:</strong></p><p>The internal thoracic artery descends posterior to the first six costal cartilages and intervening intercostal spaces, about 1 cm lateral to the lateral sternal border, and divides at the level of the sixth intercostal space into musculophrenic and superior epigastric branches.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options :- Option A: As the artery descends in the thorax almost vertically to its bifurcation, lying behind pectoralis major, the first six costal cartilages, external intercostal membranes, internal intercostals, and terminations of the upper six intercostal nerves. Option B: Artery is accompanied by a chain of lymph nodes and by venae comitantes that unite at about the third costal cartilage Option D: The internal thoracic artery descends anteromedially behind the sternal end of the clavicle, the internal jugular and brachio- cephalic veins, and the first costal cartilage</p>\n<p><strong>Extraedge:</strong></p><p>Both the right and left internal thoracic arteries are used as standard in coronary artery bypass grafting (CABG), reflecting successful long-term outcomes.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which among the following is not a branch of the internal mammary artery?", "options": [{"label": "A", "text": "Musculophrenic Artery", "correct": false}, {"label": "B", "text": "Anterior intercostal artery", "correct": false}, {"label": "C", "text": "Posterior intercostal artery", "correct": true}, {"label": "D", "text": "Sternal artery", "correct": false}], "correct_answer": "C. Posterior intercostal artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior intercostal artery 11 paired arteries constitute the posterior intercostal arteries . The first two intercostal spaces are supplied by the superior intercostal artery, and the remaining nine are supplied by separate branches from the descending thoracic aorta. The right-sided arteries are longer as the aorta lies to the left of the midline. They pass in front of the vertebrae and behind the azygos venous system, esophagus, and thoracic duct. The left-sided arteries run posteriorly adjacent to the vertebrae and enter into the intercostal space.</p>\n<p><strong>Highyeild:</strong></p><p>The superior intercostal artery is the descending branch of the costocervical trunk, which arises from the second part of the subclavian artery. It enters the thorax anterior to the neck of the first rib with the sympathetic trunk on its medial side.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: Option A: Musculophrenic artery -arises from internal thoracic artery The musculophrenic artery passes inferno-laterally behind the seventh to ninth costal cartilages, traverses the diaphragm near the ninth, and ends near the last intercostal space. Option B: It is a branch of the internal thoracic artery Anterior intercostal arteries are distributed to the upper six intercostal spaces. They pass laterally along the borders of the space and anastomose with the posterior intercostal arteries and their collateral branches Option D: Sternal branch - it is a branch of the internal thoracic artery Sternal branches are distributed to the transversus thoracis, the periosteum of the posterior sternal surface, and the sternal red bone marrow.</p>\n<p><strong>Extraedge:</strong></p><p>Along with the anterior intercostal arteries, the posterior intercostal arteries supply the muscles and skin within the intercostal spaces as well as the parietal pleura. Branches of the spinal extension anastomose with other vessels supply the nerve roots and/or spinal cord (via the anterior and posterior spinal arteries). The musculocutaneous branches supply the paraspinal soft tissue structures of the back.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 23 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Ulnar paradox means:", "options": [{"label": "A", "text": "High-level injury- less severe claw hand", "correct": true}, {"label": "B", "text": "Low-level injury- less severe claw hand", "correct": false}, {"label": "C", "text": "High-level injury- more severe claw hand", "correct": false}, {"label": "D", "text": "Low- level more severe claw hand", "correct": false}], "correct_answer": "A. High-level injury- less severe claw hand", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>High-level injury- less severe claw hand If the ulnar nerve is injured at the elbow, the clawing of the fingers is less, because the medial half of flexor digitorum profundus (flexor of proximal and distal interphalangeal joints) also gets paralyzed. If the ulnar nerve is injured at the wrist, the clawing of the fingers is more as intact flexor digitorum profundus flexes the digits more. Thus if the lesion is proximal (near the elbow), clawing is less.</p>\n<p><strong>Extraedge:</strong></p><p>On the contrary, if the lesion is distal (near the wrist), clawing is more. This is termed an ‘ action of paradox ’/ ulnar paradox. So according to the above explanation Option A and Option D, both can be correct but the best answer to the Ulnar paradox condition will be High-level injury- less severe claw hand.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Froment’s sign is seen in:", "options": [{"label": "A", "text": "Ulnar Nerve Palsy", "correct": true}, {"label": "B", "text": "Posterior interosseous nerve", "correct": false}, {"label": "C", "text": "Radial nerve palsy", "correct": false}, {"label": "D", "text": "Median nerve palsy", "correct": false}], "correct_answer": "A. Ulnar Nerve Palsy", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ulnar Nerve Palsy Froment’s test is done to check the integrity of the adductor pollicis muscle which is supplied by the ulnar nerve. Froment’s Test If the ulnar nerve is normal - the patient holds the paper between the thumb and index finger - the test is negative But, in ulnar nerve injury - compensatory flexion occurs at the interphalangeal joint of the thumb to hold the paper - Froment’s sign- test is positive.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B, C, and D. are incorrect answers because nonother nerves give innervation to the adductor pollicis muscle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The superficial branch of the ulnar nerve supplies:", "options": [{"label": "A", "text": "Abductor Pollicis", "correct": false}, {"label": "B", "text": "Palmaris brevis", "correct": true}, {"label": "C", "text": "Abductor digiti minimi", "correct": false}, {"label": "D", "text": "Opponens pollicis", "correct": false}], "correct_answer": "B. Palmaris brevis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Palmaris brevis Ulnar nerve: The superficial branch of the Ulnar nerve supplies palmaris brevis and gives digital branches to medial 1½ digits including medial 1½ nail beds till the distal interphalangeal joints.</p>\n<p><strong>Highyeild:</strong></p><p>Muscles innervated by Ulnar nerve:</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: C. Abductor digiti minimi The deep branch of the Ulnar nerve supplies most of the intrinsic muscles of the hand. At first, it supplies three muscles of hypothenar eminence , ( Abductor digiti minimi muscle, Flexor digiti minimi brevis muscle, and Opponens digiti minimi muscles). Running in the concavity of deep palmar arch, it gives branches to 4th and 3rd lumbricals from the deep aspect and also innervates dorsal interossei and palmar interossei muscles and ends by giving innervation to Adductor pollicis muscle. Since it supplies most of the intrinsic muscles of the hand responsible for finer movements, this nerve is called the ‘musician’s nerve’. Option: D. Opponens pollicis Both abductor pollicis and Opponens pollicis are muscles of thenar eminences and are supplied by the median nerve mainly.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Ulnar nerve injury at arm leads to all, except:", "options": [{"label": "A", "text": "Sensory loss of the medial 1/3rd of hand", "correct": false}, {"label": "B", "text": "Weakness of hypothenar muscles", "correct": false}, {"label": "C", "text": "Claw hand", "correct": false}, {"label": "D", "text": "Adducted thumb", "correct": true}], "correct_answer": "D. Adducted thumb", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Adducted thumb The ulnar nerve supplies adductor pollicis so palsy leads to an abducted thumb not adducted thumb.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Sensory loss of the medial 1/3rd of hand Option: B. Weakness of hypothenar muscles Option: C. Claw hand All of the above features are seen in ulnar nerve injury. Flattening of the medial border of the forearm Loss of flexion at distal interphalangeal joints of 4th and 5th digits Loss of hypothenar eminence Loss of adduction of the thumb Loss of abduction of all fingers except little finger Loss of adduction of 2nd, 4th and 5th digits Slight clawing of 2nd and 3rd digits Marked clawing of 4th and 5th digits Sensory, trophic, and vasomotor changes Clinical features of options A, B and C are seen in case of ulnar nerve injury.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "In the arm, the ulnar nerve gives a muscular branch to which muscle?", "options": [{"label": "A", "text": "Flexor Carpi Ulnaris", "correct": false}, {"label": "B", "text": "Flexor digitorum profundus", "correct": false}, {"label": "C", "text": "Both of the above", "correct": false}, {"label": "D", "text": "None of the above", "correct": true}], "correct_answer": "D. None of the above", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>None of the above The ulnar nerve gives no branch in the arm so Option D is the correct answer. The flexor carpi ulnaris and medial half of the Flexor digitorum profundus are supplied by the ulnar nerve in the forearm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 15 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A 45-year-old car mechanic presented to the emergency department with sudden onset right arm pain and swelling. During his routine work of hammering, he heard a ‘pop’ sound and his right arm gave away. On examination, the following finding was seen. The clinician made the diagnosis of a bicipital tendon tear. Which of the following is the site of attachment of the biceps tendon?", "options": [{"label": "A", "text": "1", "correct": false}, {"label": "B", "text": "2", "correct": false}, {"label": "C", "text": "3", "correct": true}, {"label": "D", "text": "4", "correct": false}], "correct_answer": "C. 3", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393275530-QTDA074001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>3 The above clinical scenario describes a bicipital tendon tear. The image depicts a Popeye sign. The Biceps tendon is attached to the radial tuberosity.</p>\n<p><strong>Highyeild:</strong></p><p>The biceps brachii is inserted into the rough posterior part of the radial tuberosity. The anterior part of the radial tuberosity is covered by a bursa. The supinator is inserted into the upper part of the lateral surface. The pronator teres are inserted into the middle of the lateral surface. The brachioradialis is inserted into the lowest part of the lateral surface just above the styloid process. The radial head of the flexor digitorum superficialis originates from the anterior oblique line and the upper part of the anterior border. The flexor pollicis longus originates from the upper two-thirds of the anterior surface. The brachialis is inserted into the anterior surface of the coronoid process including the ulnar tuberosity. The supinator arises from the supinator crest and the triangular area in front of the crest. The ulnar head of the flexor digitorum superficialis arises from a tubercle at the upper end of the medial margin of the coronoid process. The ulnar head of the pronator teres arises from the medial margin of the coronoid process. Attachments of the right radius and ulna: Proximal anterior aspect</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. 1- Supinator is inserted into the upper part of the lateral surface of the Option: B. 2- The ulnar head of flexor digitorum superficialis arises from a tubercle at the upper end of the medial margin of the coronoid process of the ulna. Option: D. 4- The brachialis is attached to the anterior surface of the coronoid surface including the ulnar tuberosity.</p>\n<p><strong>Extraedge:</strong></p><p>Madelung’s deformity is dorsal subluxation (displacement) of the lower end of the ulna, due to retarded growth of the lower end of the radius.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 20-year-old male fell from a bike. He was relatively unharmed but was starting to feel some pain along the radial aspect of the wrist in the anatomical snuff box. He went to a doctor who suspected a diagnosis of scaphoid bone fracture? Which of the following muscles, their origin, and their relation to the anatomical snuff box is correctly matched?", "options": [{"label": "A", "text": "Extensor pollicis longus - 1 - lateral border", "correct": false}, {"label": "B", "text": "Extensor pollicis longus - 2 - medial border", "correct": false}, {"label": "C", "text": "Extensor pollicis brevis - 4 - medial border", "correct": false}, {"label": "D", "text": "Abductor pollicis longus - 3 -lateral border", "correct": true}], "correct_answer": "D. Abductor pollicis longus - 3 -lateral border", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393276164-QTDA074002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Abductor pollicis longus - 3 -lateral border The tendons of two of the outcropping muscles make up the lateral border of the anatomical snuffbox ; they are the abductor pollicis longus and extensor pollicis brevis. The medial border of the snuffbox is made up of the remaining outcropping muscle, the extensor pollicis longus. Attachments Of Right Radius And Ulna:Posterior Proximal Aspect</p>\n<p><strong>Highyeild:</strong></p><p>Anatomical snuffbox is triangularly shaped, it has three borders, a floor, and a roof: Ulnar (medial) border: Tendon of the extensor pollicis longus. Radial (lateral) border: Tendons of the extensor pollicis brevis and abductor pollicis longus. Proximal border: Styloid process of the Floor: Carpal bones; scaphoid and trapezium. Roof: Skin. Boundaries of anatomical snuff box</p>\n<p><strong>Extraedge:</strong></p><p>The main contents of the anatomical snuffbox are the radial artery, a branch of the radial nerve, and the cephalic vein. The radial artery crosses the floor of the anatomical snuffbox in an oblique manner. It runs deep to the extensor tendons.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A father was playing with his 3 year old child in a local park. He started swinging the child with his arms. Suddenly the child started screaming in pain. He took the child to a doctor, who told the father that he need not worry. He promptly reduced the arm to its normal position and the condition resolved. Which of the following conditions did the child suffer from?", "options": [{"label": "A", "text": "Draftsman's elbow", "correct": false}, {"label": "B", "text": "Nursemaid’s elbow", "correct": true}, {"label": "C", "text": "Impingement syndrome", "correct": false}, {"label": "D", "text": "Painful arc syndrome", "correct": false}], "correct_answer": "B. Nursemaid’s elbow", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Nursemaid’s elbow The given clinical scenario suggests radial head dislocation due to sudden jerky movement while swinging the child. This condition is also known as pulled elbow.</p>\n<p><strong>Highyeild:</strong></p><p>Nursemaid's elbow occurs when there is a partial separation of the radiocapitellar joint. Because a young child's ligaments—the strong tissues that attach bones to each other—are not fully formed, even a gentle force on the joint may cause it to shift, or partially dislocate. The annular ligament surrounds the radius and may be particularly loose in some young children, which may lead to the nursemaid's elbow recurring over and over again. Nursemaid's elbow</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Draftsman's elbow Draftsman's elbow or olecranon bursitis, This condition affects the small fluid sacs or bursae in the elbow. These fluid sacs aid in the movement of the elbow. Leaning on the elbow for a long time, a sharp blow, or an infection could be the cause of this condition. Option: C. Impingement syndrome Shoulder impingement syndrome is the result of a vicious cycle of rubbing of the rotator cuff between your humerus and top outer edge of your shoulder. The rubbing leads to more swelling and further narrowing of the space, which result in pain and irritation. Option:D. Painful arc syndrome Painful arc is a syndrome characterized by severe pain in the shoulders; it is commonly known as Shoulder Impingement Syndrome. Symptoms usually occur when the arms are raised overhead or above shoulder level, or when the arm is moved from sideways to the body. Commonly involves supraspinatus tendon.</p>\n<p><strong>Extraedge:</strong></p><p>In most cases of a nursemaid's elbow, the doctor will gently move the bones back into normal position. The medical term for this procedure is \"reduction.\" The doctor will hold the child's wrist or forearm and turn the hand so that it faces palm up. While putting pressure near the top of the radius bone with his or her thumb, the doctor will slowly bend the elbow. A faint pop or click may be heard when the joint goes back into place.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 22 year old man comes to the emergency department after falling on his outstretched right hand. He complains of pain, swelling and deformity at distal forearm. X-rays of the affected area are shown. What is the age by which the affected area fuses with the shaft?", "options": [{"label": "A", "text": "1st Year", "correct": false}, {"label": "B", "text": "4th year", "correct": false}, {"label": "C", "text": "20th year", "correct": true}, {"label": "D", "text": "18th year", "correct": false}], "correct_answer": "C. 20th year", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393276469-QTDA074004IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>20th year The clinical history and X-ray image suggest Colles’ fracture which is a fracture of the lower end of the radius with a distal fragment displaced upwards and backward. The lower end of the radius ossifies from a secondary center which appears during the first year and fuses with the shaft by the 20th year.</p>\n<p><strong>Highyeild:</strong></p><p>The radius commonly gets fractured about 2 cm above its lower end (Colles’ fracture). This fracture is caused by a fall on the outstretched hand. The distal fragment is displaced upwards and backward, and the radial styloid process comes to lie proximal to the ulnar styloid process. (It normally lies distal to the ulnar styloid process.) If the distal fragment gets displaced anteriorly, it is called Smith’s fracture. (a) Colles’ fracture with dinner fork deformity, and (b) Smith’s fracture</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A & C. The lower end of the radius ossifies from a secondary center which appears during the first year and fuses with the shaft by the 20th year. Option: C. The lower end of the radius ossifies from a secondary center which fuses with the shaft by 20th year. Option: B & D. The upper end of the radius ossifies from a secondary center which appears during the 4th year and fuses with the shaft at 18th year.</p>\n<p><strong>Extraedge:</strong></p><p>A Smith fracture is a break to the end of the radius . The end part of the bone, which forms part of the wrist joint, is displaced or angled in the direction of the palm of the hand. Often, this injury occurs by a fall to the back of a flexed wrist but can occur in any fall to an outstretched hand. Injury resulting from a fall on the palm of the hand, the dorsum or ulno‐dorsum of the hand, or a fisted hand or a direct blow to the back of the wrist causing a volar displacement of the distal radius.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 30 year old man comes to the emergency department after falling on elbow. X ray elbow shows fracture of olecranon process. What is the age of the appearance of the ossification center which forms the olecranon process?", "options": [{"label": "A", "text": "10th Year", "correct": true}, {"label": "B", "text": "16th year", "correct": false}, {"label": "C", "text": "5th year", "correct": false}, {"label": "D", "text": "18th year", "correct": false}], "correct_answer": "A. 10th Year", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>10th Year The superior part of the olecranon process ossifies from a secondary center which appears during the 10th year</p>\n<p><strong>Highyeild:</strong></p><p>Ossification of Ulna The shaft and most the upper end of ulna ossify from a primary center which appears during the 8th week of development. The superior part of the olecranon process ossifies from a secondary center which appears during the 10th year. It forms a scale-like epiphysis which joins the rest of the bone by 16th year. The lower end ossifies from a secondary center which appears during the 5th year, and joins with the shaft by 18th year. This is the growing end of the bone.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. The superior part of the olecranon process ossifies from a secondary center which fuses with the rest of the bone by 16th year Option: C & D. The lower end of the ulna ossifies from a secondary center which appears during the 5th year and fuses with the shaft by 18th year.</p>\n<p><strong>Extraedge:</strong></p><p>Ossification of Radius The shaft of radius ossifies from a primary center which appears during the 8th week of development. The lower end ossifies from a secondary center which appears during the first year and fuses with the shaft at 20th year; it is the growing end of the bone. The upper end (head) ossifies from a secondary center which appears during the 4th year and fuses with shaft at 18th year.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The radius and ulna are joined to each other at three places: Superior, Middle and Inferior radioulnar joints. What is the type of the middle radioulnar joint?", "options": [{"label": "A", "text": "Pivot type of synovial joint", "correct": false}, {"label": "B", "text": "Syndesmosis", "correct": true}, {"label": "C", "text": "Hinge type of synovial joint", "correct": false}, {"label": "D", "text": "Synchondrosis", "correct": false}], "correct_answer": "B. Syndesmosis", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Syndesmosis Syndesmosis is defined as a fibrous joint in which two adjacent bones are linked by a strong membrane or ligaments. Eg: Tibiofibular syndesmosis, Middle radioulnar joint attached by interosseous membrane.</p>\n<p><strong>Highyeild:</strong></p><p>Syndesmoses are slightly movable joints (amphiarthrosis). In syndesmosis joints, the two bones are held together by an interosseous membrane. For example, the tibia connects to the fibula, forming the middle tibiofibular joint, and the ulna attaches to the radius, forming the middle radio-ulnar joint. The tibiofibular syndesmosis is a complex fibrous joint composed of multiple ligaments and a broad fibrous interosseous membrane that spans between the tibia and fibula throughout the length of both bones. It is an important structure for ankle stability.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option: A. Superior and inferior radioulnar joints are pivot type of synovial joint which are responsible for supination and pronation of the forearm Option: C. Elbow joint is an example of hinge type of synovial joint Option: D. Synchondrosis is a type of primary cartilaginous joint where hyaline cartilage completely joins together two bones. Eg: first sternocostal joint</p>\n<p><strong>Extraedge:</strong></p><p>Schindylesis is an articulation in which two bones are joined by fitting the ridge of one bone into the groove of another. Also known as a \"wedge-and-groove\" joint. This fibrous suture joint can be found between the vomer and the perpendicular plate of the ethmoid bone as well as between the vomer and the gap between the maxilla and palatine.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "While doing a neurological examination physician asks the patient to extend his flexed elbow against resistance. What is the insertion of the muscle tested?", "options": [{"label": "A", "text": "A", "correct": true}, {"label": "B", "text": "B", "correct": false}, {"label": "C", "text": "C", "correct": false}, {"label": "D", "text": "D", "correct": false}], "correct_answer": "A. A", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393276775-QTDA074008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A The muscle tested in the neurological examination is triceps brachii. It is responsible for elbow extension. One can safely ignore options C & D as a muscle extending the elbow can never insert into the anterior surface of the elbow Option A. Triceps brachii is inserted into the rough posterior part of the superior surface of the olecranon process.</p>\n<p><strong>Highyeild:</strong></p><p>Attachments of right radius and ulna: Anterior aspect</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option: B. Site of attachment of Anconeus: Lateral aspect of the olecranon process and the upper one-fourth of the posterior surface of the shaft Option: C. Site of attachment of Brachialis: Anterior surface of the coronoid process Option: D. Site of attachment of flexor digitorum profundus: the upper three-fourths of the anterior and medial surfaces of the shaft.</p>\n<p><strong>Extraedge:</strong></p><p>Attachments Of Right Radius And Ulna: Posterior Aspect</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 17 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which of the following below is Posteriorly related to foramen of Winslow?", "options": [{"label": "A", "text": "Liver", "correct": false}, {"label": "B", "text": "Duodenum", "correct": false}, {"label": "C", "text": "Inferior vena cava", "correct": true}, {"label": "D", "text": "Pancreas", "correct": false}], "correct_answer": "C. Inferior vena cava", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Inferior vena cava This is a large recess of the peritoneal cavity behind the stomach, the lesser omentum, and the caudate lobe of the liver. It is closed all around, except in the upper part of its right border, where it communicates with the greater sac through the epiploic foramen.</p>\n<p><strong>Highyeild:</strong></p><p>BOUNDARIES OF LESSER SAC Anterior Peritoneum covering caudate lobe and caudate process of liver. The posterior layer of the lesser omentum Peritoneum covers the posterior surface of the stomach The second layer of the greater omentum. Posterior The third layer of the greater omentum. Peritoneum covering the anterior superior surface of the transverse colon. The upper layer of the transverse mesocolon. Peritoneum covers the anterior surface of the body of the pancreas, left suprarenal, left kidney, splenic vessels, and diaphragm.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During the laparoscopic cholecystectomy in a 40-year-old female patient, accidentally the hepatoduodenal ligament was clamped instead of the cystic artery. Which of the following vessels would most likely be occluded in this iatrogenic injury?", "options": [{"label": "A", "text": "Superior Mesenteric Artery", "correct": false}, {"label": "B", "text": "Proper hepatic artery", "correct": true}, {"label": "C", "text": "Splenic artery", "correct": false}, {"label": "D", "text": "Common hepatic artery", "correct": false}], "correct_answer": "B. Proper hepatic artery", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Proper hepatic artery The proper hepatic artery is the only artery typically within the hepatoduodenal ligament and, therefore, would be occluded. This artery lies within the right anterior free margin of Winslow's omental (or epiploic) foramen.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The superior mesenteric artery branches from the abdominal aorta inferior to the hepatoduodenal ligament. Option: C. The splenic artery runs behind the stomach and is not in the hepatoduodenal ligament. Option: D. The common hepatic artery originates from the proper hepatic artery but does not run within the hepatoduodenal ligament.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 58-year-old male alcoholic is admitted to the hospital after vomiting dark red blood (hematemesis). Endoscopy reveals ruptured esophageal varices, most likely resulting from portal hypertension. Which of the following venous tributaries to the portal system anastomoses with caval veins to cause the varices?", "options": [{"label": "A", "text": "Splenic", "correct": false}, {"label": "B", "text": "Left gastro-omental", "correct": false}, {"label": "C", "text": "Left gastric", "correct": true}, {"label": "D", "text": "Left hepatic", "correct": false}], "correct_answer": "C. Left gastric", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Left gastric The left gastric vein carries blood from the stomach to the portal vein. At the esophageal-gastric junction, the left gastric vein (portal system) anastomoses with esophageal veins (canal system). High blood pressure in the portal system causes high pressure in this anastomosis, causing the ruptured esophageal varices.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The splenic vein and its tributaries carry blood away from the spleen and do not form a caval-portal anastomosis. Option: B. The left gastro-omental vein accompanies the left gastro-omental artery and joins the splenic vein with no direct anastomosis with caval veins. Option: D. The left hepatic vein is a caval vein and empties into the inferior vena cava.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 52-year-old man presents to the emergency department complaining of persistent severe right upper quadrant pain for the past 2 hours. During that period of time, he felt nauseated, was sweating profusely, and also experienced pain in the posterior aspect of his right shoulder. The pain began shortly after a lunch consisting of \"fast food\". Ultrasound examination reveals multiple stones in an inflamed gallbladder with a normal bile duct. Which of the following spinal nerve segments are involved in the shoulder pain, associated with cholecystitis?", "options": [{"label": "A", "text": "C3 To C5", "correct": false}, {"label": "B", "text": "C5 to C8", "correct": false}, {"label": "C", "text": "T1 to T4", "correct": false}, {"label": "D", "text": "T5 to T9", "correct": true}], "correct_answer": "D. T5 to T9", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>T5 to T9 Referred pain from cholecystitis is generally referred to the region of the inferior angle of the right scapula. These fibers are generally from T5 to T9. These sensory fibers for pain are stimulated by gallbladder inflammation because of the proximity of the adjacent structures.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. C3 to C5 sensory fibers innervate the shoulder area. Option: B. The distribution of C5 to C8 is primarily to the upper limb, to the level of the hand; Option: C. T1 to T4 distribution is to the upper thoracic wall and medial upper arm; T1 to T4 visceral fibers for pain are generally associated with referred pain from the heart.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A hard mass (a fecalith) in the ostium of a 27-year old patient's appendix had led to a local infection (appendicitis) with a slightly elevated temperature and a moderate increase in WBC count. The initial pain from the infection was dull and difficult to localize, but the patient placed his hand in the periumbilical area to indicate the general area of discomfort. The region of the umbilicus receives its sensory supply, classically, from which of the following spinal nerves?", "options": [{"label": "A", "text": "T7", "correct": false}, {"label": "B", "text": "T8", "correct": false}, {"label": "C", "text": "T10", "correct": true}, {"label": "D", "text": "T12", "correct": false}], "correct_answer": "C. T10", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>T10 The dermatome of spinal nerve level T10 crosses the level of the umbilicus; Pain from appendicitis is most often perceived at first in the periumbilical region, reflecting the level of embryologic spinal nerve supply to the appendix, which is from T10. When the appendix swells or ruptures and contacts the body wall, somatic sensory fibers of the adjacent body wall cause the apparent site of pain to shift to the lower right abdominal quadrant.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Dermatome of T7 is the level of the xiphoid process. Option: B. T8 and T9 dermatomes lie between the two preceding spinal nerve levels. Option: D. T12 innervates the lowest portion of the rectus abdominis and overlying skin with motor and sensory supply, respectively.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "If cirrhosis causes obstruction of the portal circulation within the liver, portal blood could still be conveyed to the caval system via which of the following?", "options": [{"label": "A", "text": "Azygos and hemiazygos veins", "correct": true}, {"label": "B", "text": "Gonadal veins", "correct": false}, {"label": "C", "text": "Internal iliac veins", "correct": false}, {"label": "D", "text": "Splenic vein", "correct": false}], "correct_answer": "A. Azygos and hemiazygos veins", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Azygos and hemiazygos veins The oesophagal venous plexus, which drains into the azygos and hemiazygos veins within the thorax, has anastomoses with branches of the left gastric vein. Thus, following blockage of the portal vein, portal blood may enter the superior vena cava via the azygos system. Other important portocaval connections include the superior rectal vein with the middle and inferior rectal veins; paraumbilical and epigastric veins (engorgement of these vessels results in caput-medusae); and the colic and splenic veins with renal veins and veins of the posterior body wall. The gonadal veins exclusively drain the gonads (although in the female, the ovarian vein communicates with the uterovaginal plexus). These vessels have no anastomoses with portal veins. The internal iliac veins, which drain most of the pelvis and much of the inferior extremities, have no demonstrated portal anastomoses. The splenic vein is incorrect because it is a component of the portal venous system. The vesical venous plexus, situated well within the pelvis and drains the bladder and the prostate (or uterus and vagina),1 has no association with portal vessels.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following below is/are true statements about the relations of portal vein?", "options": [{"label": "A", "text": "Origin is posterior to the head of the pancreas", "correct": false}, {"label": "B", "text": "Ascends behind the second part of duodenum", "correct": false}, {"label": "C", "text": "Ascends inside the hepatogastric ligament till the hilum of the liver", "correct": true}, {"label": "D", "text": "Forms posterior boundary of Epiploic foramen", "correct": false}], "correct_answer": "C. Ascends inside the hepatogastric ligament till the hilum of the liver", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ascends inside the hepatogastric ligament till the hilum of the liver Portal vein is formed by joining Superior mesenteric & splenic veins behind the neck of pancreas. It ascends behind the first part of duodenum in lesser omentum / Hepato-gastric ligament with bile duct to right & hepatic artery to left. It forms the anterior boundary of Epiploic foramen. Its posterior boundary is formed by IVC.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Major Porto- caval shunting is seen in all of the following except? Umbilicus Oesophagus Rectum and anal canal Bare area of liver Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1, 2, 3", "correct": false}, {"label": "B", "text": "1, 2, 4", "correct": false}, {"label": "C", "text": "2, 3, 4", "correct": false}, {"label": "D", "text": "1, 2, 3, 4", "correct": true}], "correct_answer": "D. 1, 2, 3, 4", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1, 2, 3, 4</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 18 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "A genetic coding error during the 5th week of development causes a unilateral failure of development of the ureteric bud. This condition would directly affect the formation of which of the following structures?", "options": [{"label": "A", "text": "Proximal Convoluted Tubules", "correct": false}, {"label": "B", "text": "Renal glomeruli", "correct": false}, {"label": "C", "text": "Urinary bladder", "correct": false}, {"label": "D", "text": "Ureter", "correct": true}], "correct_answer": "D. Ureter", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Ureter As ureter is derived from ureteric bud therefore development of ureter will be affected.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. The metanephric mesoderm forms the nephrons in the kidney, including Bowman's capsule, the proximal convoluted tubule, loop of Henle, and distal convoluted tubule. Nephrons are formed throughout prenatal development. Option: B. Renal glomeruli are small capillary bundles that form in association with the Bowman capsule. They are not derived from either the ureteric bud or the metanephric mesoderm. Option: C. The urinary bladder is derived from the cloaca. The cloaca divides into a urogenital sinus and an anal canal, which are located anterior and posterior, respectively. The urogenital sinus subsequently differentiates into the urinary bladder and urethra.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following structures lie anterior to the left ureter? Gonadal Artery Left colic artery Pelvic colon Internal iliac artery Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1,2,3,4", "correct": false}, {"label": "B", "text": "1,2", "correct": false}, {"label": "C", "text": "3,4", "correct": false}, {"label": "D", "text": "1,2,3", "correct": true}], "correct_answer": "D. 1,2,3", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>1,2,3 Anteriorly On the right side, the ureter is related to: Third part of the duodenum Peritoneum Right colic vessels Ileocolic vessels Gonadal vessels Root of the mesentery Terminal part of the ileum. On the left side the ureter is related to: Peritoneum Gonadal artery Left colic vessels Sigmoid colon Sigmoid mesocolon. Posteriorly The ureter lies on Psoas major Tips of transverse processes Genitofemoral nerve.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 32yr old male patient presents with complaints of right flank pain. His CBC, urine and RFT were normal. Abdominal USG showed right hydronephrosis. A retrograde ureteropyelogram showed a right sided fish hook ureter with hydronephrosis. The abnormality is:", "options": [{"label": "A", "text": "Incomplete fusion of urethral folds", "correct": false}, {"label": "B", "text": "Failure of fusion of paramesonephric duct", "correct": false}, {"label": "C", "text": "Two ureteric buds arising from mesonephric duct", "correct": false}, {"label": "D", "text": "Persistence of posterior cardinal vein", "correct": true}], "correct_answer": "D. Persistence of posterior cardinal vein", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Persistence of posterior cardinal vein Retrocaval ureter: A persistence of the posterior cardinal vein, associated with high confluence of the right and left common iliac veins or a double inferior vena cava, may result in a retrocaval (or circumcaval) ureter that passes behind the inferior vena cava, usually at the level of the inferior edge of the third part of the duodenum, before it emerges anterior to it to pass from medial to lateral. Retrocaval ureter occurs in 1 in 1500 individuals. Commonly, it has no clinical sequelae, although it can result in upper ureteric obstruction.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "According to Weigert Meyer rule duplication of ureter, the lower pole ureter in urinary bladder is?", "options": [{"label": "A", "text": "Medial & caudal to upper pole ureter", "correct": false}, {"label": "B", "text": "Lateral & caudal to upper pole ureter", "correct": false}, {"label": "C", "text": "Medial & cephalad to upper pole ureter", "correct": false}, {"label": "D", "text": "Lateral & cephalad to upper pole ureter", "correct": true}], "correct_answer": "D. Lateral & cephalad to upper pole ureter", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lateral & cephalad to upper pole ureter The ureter from the upper pole of the kidney (the longer ureter) inserts more medially and caudally in the bladder than the ureter from the lower pole (Weigert–Meyer rule). Duplex ureters: In 1 in 125 individuals, two ureters drain the renal pelvis on one side; this is termed a duplex system. Bilateral duplex ureters occur in approximately 1 in 800 cases. Duplex ureters are the product of two ureteric buds arising from the mesonephric duct; they share a single fascial sheath and may either fuse at any point along their course, or remain separate until they insert through separate ureteric orifices into the bladder. Care must be taken not to compromise the blood supply of the second ureter when exercising or reimplanting a single ureter of a duplex. This reflects the embryological development of the ureter: the ureteric bud that is initially more proximal on the mesonephric duct has a shorter time to be pulled cranially in the bladder and so it inserts more distally in the mature bladder. The ureter from the lower pole has a shorter intramural course than the longer ureter and is prone to reflux.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "22-Year-old woman is involved in a motor vehicle collision. Her complaints are consistent with a pelvic fracture and a CT scan is ordered to rule out internal bleeding. The CT shows no bleeding and that her uterus is in the most typical position. What is this position?", "options": [{"label": "A", "text": "Anteflexed and Retroverted", "correct": false}, {"label": "B", "text": "Retroflexed and anteverted", "correct": false}, {"label": "C", "text": "Anteflexed and anteverted", "correct": true}, {"label": "D", "text": "Retroflexed and retroverted", "correct": false}], "correct_answer": "C. Anteflexed and anteverted", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anteflexed and anteverted The normal position of the uterus in most women is anteflexion and Anteversion. Anteflexion is the forward bending of the long axis of the uterus about the cervix at the level of the internal os. Anteversion is the forward bending of the long axis of the uterus about the long axis of the vagina</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. - Retro-version is the backward bending of the long axis of the uterus in relation to the long axis of the vagina. Option: B & D. - Retroflexion is the backward bending of the long axis of the uterus in relation to the cervix at the level of the internal os.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 15 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Choose the INCORRECT Option regarding marked white matter structure.", "options": [{"label": "A", "text": "A- Internal Capsule", "correct": false}, {"label": "B", "text": "B- cingulum", "correct": true}, {"label": "C", "text": "C- Forceps minor", "correct": false}, {"label": "D", "text": "D- Forceps major", "correct": false}], "correct_answer": "B. B- cingulum", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392958252-QTDA068001IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>B- cingulum B is marked on Tapetum fibers, which form the lateral relation of the posterior horn of the lateral ventricle.</p>\n<p><strong>Highyeild:</strong></p><p>The corpus callosum, also callosal commissure, is a wide, thick nerve tract consisting of a flat bundle of commissural fibers beneath the cerebral cortex in the brain. The corpus callosum is only found in placental mammals. It spans part of the longitudinal fissure, connecting the left and right cerebral hemispheres, enabling communication between them. It is the largest white matter structure in the human brain, about 10 inches (250 mm) long and consisting of 200–300 million axonal projections.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option: A. A- Internal Capsule Option: C. C- Forceps minor Option: D. D- Forceps major Options A, C, and D are correctly labeled, as shown in the horizontal section of the brain above.</p>\n<p><strong>Extraedge:</strong></p><p>The corpus callosum has four main parts – individual nerve tracts connecting different hemispheres. These are the rostrum , the genu , the trunk or body , and the splenium . A narrowed part between the trunk and the splenium is known as the isthmus . Fibers from the trunk and the splenium, known together as the tapetum, form the roof of each lateral ventricle.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Choose the correct option for the marked structures.", "options": [{"label": "A", "text": "A is a type of projection fiber", "correct": false}, {"label": "B", "text": "B is the hippocampal region of the temporal lobe", "correct": false}, {"label": "C", "text": "C projects into ventro anterior nucleus of the thalamus", "correct": true}, {"label": "D", "text": "D contains anterior thalamic radiations", "correct": false}], "correct_answer": "C. C projects into ventro anterior nucleus of the thalamus", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392967285-QTDA068002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>C projects into ventro anterior nucleus of the thalamus Option C. is Globus pallidus, part of the lentiform nucleus, which projects into the ventral anterior nucleus of the thalamus and subsequently to the premotor cortex.</p>\n<p><strong>Highyeild:</strong></p><p>The globus pallidus (GP), also known as paleostriatum or dorsal pallidum, is a subcortical brain structure. The globus pallidus is a significant component of the basal ganglia, with principal inputs from the striatum and principal direct outputs to the thalamus and the substantia nigra.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. is forceps minor fibers of the corpus callosum sweeping forward to connect frontal lobes, so they are, e.g. of, commissural fibers. Option: B. Is insula (island of Reil) Option: D. Is a retro-lentiform part of an internal capsule that contains optic (posterior thalamic) radiations. Anterior thalamic radiation is located in the anterior limb of the internal capsule.</p>\n<p><strong>Extraedge:</strong></p><p>The globus pallidus is a structure in the brain involved in the regulation of voluntary movement. It is part of the basal ganglia, which, among many other functions, regulates movements that occur on the subconscious level. If the globus pallidus is damaged, it can cause movement disorders, as its regulatory function will be impaired.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Relations of internal capsule:", "options": [{"label": "A", "text": "Thalamus medially, caudate nucleus and lentiform laterally", "correct": false}, {"label": "B", "text": "Thalamus and caudate medially and lentiform laterally", "correct": true}, {"label": "C", "text": "Thalamus and caudate laterally and lentiform medially", "correct": false}, {"label": "D", "text": "Thalamus laterally, caudate nucleus and lentiform medially", "correct": false}], "correct_answer": "B. Thalamus and caudate medially and lentiform laterally", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Thalamus and caudate medially and lentiform laterally Internal capsule is located between the thalamus and caudate nucleus medially and the lentiform nucleus laterally. Internal capsule parts and relation</p>\n<p><strong>Highyeild:</strong></p><p>The internal capsule is a compact bundle of projection fibers between the thalamus and caudate nucleus medially and the lentiform nucleus laterally. These fibers fan out rostrally to form the corona radiata and condense caudally to continue as the crus cerebri of the midbrain. The internal capsule's ascending (corticopetal/sensory) and descending (corticofugal/motor) fibers chiefly interconnect the cerebral cortex with the brainstem and spinal cord. These fibers are mainly responsible for the sensory and motor innervation of the opposite half of the body.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. Thalamus medially, caudate nucleus and lentiform laterally Option:C. Thalamus and caudate laterally and lentiform medially Option:D. Thalamus laterally, caudate nucleus and lentiform medially Internal capsule is located between the thalamus and caudate nucleus medially and the lentiform nucleus laterally, therefore Option A, C and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Because of the high concentration of motor and sensory nerve fibers within the internal capsule, even a small lesion may produce widespread paralytic effects and sensory loss in the opposite half of the body.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which parts of the internal capsule are associated with optic radiation?", "options": [{"label": "A", "text": "Genu", "correct": false}, {"label": "B", "text": "Posterior limb", "correct": false}, {"label": "C", "text": "Retro lentiform", "correct": true}, {"label": "D", "text": "Sub lentiform", "correct": false}], "correct_answer": "C. Retro lentiform", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Retro lentiform Optic radiations - are associated with the retro lentiform part of the internal capsule. Auditory radiations - are associated with the sub lentiform part of the internal capsule.</p>\n<p><strong>Highyeild:</strong></p><p>Posterior thalamic radiation is directed posteriorly. The fibers of posterior thalamic radiation pass through the retrolentiform part of internal capsule and connect the lateral geniculate body to the primary visual cortex of the occipital lobe forming optic radiation (geniculocal-carine tract) Constituent motor and sensory fibers in different parts of the internal capsule Part Motor fibers Sensory fibers Anterior limb Frontopontine fibres Anterior thalamic radiation Genu • Frontopontine fibres • Corticonuclear fibres for head and neck Superior thalamic radiation (anterior part only) Posterior limb Frontopontine fibres • Corticospinal (pyramidal) fibres for upper limb, trunk and lower limb • Corticorubral (extrapyramidal) fibres Superior thalamic radiation Retrolentiform part Parietopontine and occipitopontine fibres Posterior thalamic radiation (optic radiation Sublentiform part Parietopontine and temporopontine fibres Inferior thalamic radiation (auditory radiation)</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. Genu Superior thalamic radiation (anterior part only) is associated with the genu part of the internal capsule. Option:B. Posterior limb Superior thalamic radiation is associated with the posterior part of the internal capsule. Option:D. Sub lentiform Auditory radiations - is associated with the sub lentiform part of the internal capsule.</p>\n<p><strong>Extraedge:</strong></p><p>Inferior thalamic radiation is directed inferiorly. Its fibers pass through the sub-lentiform part of the internal capsule, and most of them connect the medial geniculate body with the primary auditory area of the temporal lobe forming auditory radiation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Corticospinal fibers pass through which part of the internal capsule:", "options": [{"label": "A", "text": "Posterior one-thirds of anterior limb", "correct": false}, {"label": "B", "text": "Anterior two-thirds of posterior limb", "correct": true}, {"label": "C", "text": "Posterior two-thirds of anterior limb", "correct": false}, {"label": "D", "text": "Anterior two-thirds of anterior limb", "correct": false}], "correct_answer": "B. Anterior two-thirds of posterior limb", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior two-thirds of posterior limb The corticospinal fibers form several discrete bundles in the anterior two-thirds of the posterior limb of the internal capsule. The disposition of motor fibers passing through the internal capsule.</p>\n<p><strong>Highyeild:</strong></p><p>Pyramidal fibers arise in the cerebral cortex and relay in the lower motor neurons within the brainstem and spinal cord. The pyramidal fibers are of two types: Corticonuclear fibers synapse with the contralateral motor nuclei of the cranial nerves, which innervate the head and neck muscles. The corticonuclear fibers occupy the genu of the internal capsule. Corticospinal fibers synapse with the anterior horn cells of the opposite half of the spinal cord, which innervates the muscles of the upper limb, trunk, and lower limb. The corticospinal fibers form several discrete bundles in the anterior two-thirds of the posterior limb. The fibers for the upper limb are most anterior, followed in that order by the fibers for the trunk and the lower limb.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option:A. Posterior one-thirds of anterior limb Option:C. Posterior two-thirds of anterior limb Option:D. Anterior two-thirds of anterior limb The corticospinal fibers form several discrete bundles in the anterior two-thirds of the posterior limb of the internal capsule, therefore options A, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Extrapyramidal fibers arise in the cerebral cortex and relay into the subcortical gray matter belonging to the extrapyramidal system ( red nucleus, corpus stria-tum, substantia nigra,), etc. They are named according to their destinations, viz . corticorubral, corticostriatal, corticonigral, , respectively. Most extrapyramidal fibers occupy the position near the corticospinal fibers in the internal capsule and are therefore affected by the lesions of the posterior limb.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Association fibers are all of the following except.", "options": [{"label": "A", "text": "Uncinate Fasciculus", "correct": false}, {"label": "B", "text": "Cingulum", "correct": false}, {"label": "C", "text": "Superior longitudinal fasciculus", "correct": false}, {"label": "D", "text": "Forceps major", "correct": true}], "correct_answer": "D. Forceps major", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Forceps major The forceps major, also known as the posterior forceps, is a white matter fiber bundle that connects the occipital lobes from the splenium of the corpus callosum. The fibers of the splenium part of the corpus callosum ( Commissural fibers ) connect the posterior parts of the parietal lobes and temporal and occipital lobes of the two hemispheres. The fibers connecting the occipital lobes sweep backward on either side above the calcarine sulcus forming a large fork-like structure, the forceps major.</p>\n<p><strong>Highyeild:</strong></p><p>ASSOCIATION (ARCUATE) FIBERS These are the fibers that connect different cortical areas of the same hemisphere. These are subdivided into the following two types. Short Association Fibers These fibers connect adjacent gyri to one another. Long Association Fibers These fibers connect more widely separated gyri. Some examples are: The uncinate fasciculus, connecting the temporal pole to the motor speech area and to the orbital cortex. The cingulum connecting the cingulate gyrus to the parahippocampal gyrus is seen on the medial surface. The superior longitudinal fasciculus connects the frontal lobe to the occipital and temporal lobes. The inferior longitudinal fasciculus connecting the occipital and temporal lobes. Fronto-occipital fasciculus on the medial surface 1, 3, and 4 are better seen on the superolateral surface. Association fibers of brain</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. Uncinate Fasciculus Option:B. Cingulum Option:C. Superior longitudinal fasciculus Uncinate Fasciculus, Cingulum, and Superior longitudinal fasciculus are all examples of association fibers.</p>\n<p><strong>Extraedge:</strong></p><p>The important commissures of the brain are as follows: Corpus callosum. Anterior commissure. Posterior commissure. Hippocampal commissure (commissure of fornix). Habenular commissure</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Identify the “C” marked in the given diagram?", "options": [{"label": "A", "text": "Long Association Fibers", "correct": false}, {"label": "B", "text": "Short association fibers", "correct": false}, {"label": "C", "text": "Projection fibers", "correct": true}, {"label": "D", "text": "Commissural fibers", "correct": false}], "correct_answer": "C. Projection fibers", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392967422-QTDA068007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Projection fibers Marked structure is internal capsule Projection fibres - connect cortex to sub cortical structures • Examples- Internal capsule & Fornix</p>\n<p><strong>Highyeild:</strong></p><p>The internal capsule is a compact bundle of projection fibers between the thalamus and caudate nucleus medially and the lentiform nucleus laterally. These fibers fan out rostrally to form the corona radiata and condense caudally to continue as the crus cerebri of the midbrain. The internal capsules ascending (corticopetal/sensory) and descending (corticofugal/motor) fibers chiefly interconnect the cerebral cortex with the brainstem and spinal cord.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. Long Association Fibers Option:B. Short association fibers Option:D. Commissural fibers C marked structure is an internal capsule, and it is an example of projection fibers; therefore, options A, B, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Damage to the internal capsule due to hemorrhage or infarction leads to loss of sensations and spastic paralysis of the opposite half of the body (contralateral hemiplegia). The hemorrhage commonly occurs due to a rupture of the artery of cerebral hemorrhage (also called Charcot's artery of cerebral hemorrhage), which supplies the posterior limb of the internal capsule. The spastic paralysis of the opposite half of the body occurs due to the involvement of the pyramidal and extrapyramidal fibers for the upper limb, trunk, and lower limb.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were posted in radiology during your internship, where you were studying the different sequences used in MRI. One such sequence is given below, showing the white matter fibers. Which of the following types of fibers are represented by this image?", "options": [{"label": "A", "text": "Association Fibers", "correct": true}, {"label": "B", "text": "Commissural fibers", "correct": false}, {"label": "C", "text": "Projection fibers.", "correct": false}, {"label": "D", "text": "All of the above.", "correct": false}], "correct_answer": "A. Association Fibers", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392967446-QTDA068008IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Association Fibers In the given MRI sequence, known as diffusion tensor imaging, the association fibers are seen. These are also known as fasciculus. They connect different areas in the same hemisphere. From the given image, we can see both the cerebral hemispheres have their own association fibers. Hence, the correct answer will be option A.</p>\n<p><strong>Highyeild:</strong></p><p>The fibers of white matter connect the various parts of the cerebral cortex and to the other parts of the central nervous system. They are classified into the following three types based on the types of connections they provide. Association fibers The association fibers interconnect the different regions of the cerebral cortex in the same hemisphere (intrahemispheric fibers). Commissural fibers The commissural fibers interconnect the identical/corresponding areas of the two cerebral hemispheres (interhemispheric fibers). The bundles of such fibers are termed commissures. Projection fibers The projection fibers connect the cerebral cortex to the subcortical centers (such as the corpus striatum, thalamus, and brainstem) and spinal cord.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B . Commissural fiber- they are fibers connecting the same areas of both the cerebral hemispheres. Option: C. Projection fibers- these are corticopetal or corticofugal fibers. Option: D. Therefore, all of the above is an incorrect answer.</p>\n<p><strong>Extraedge:</strong></p><p>The projection fibers of the neocortex constitute the corona radiata and internal capsule, while those of the allocortex (i.e., archicortex and paleocortex) constitute the fimbria and fornix. The most important bundles of projection fibers are the internal capsule and fornix.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A female child with recurrent episodes of seizures and mental retardation underwent MRI, which showed the following finding. Which of the following are the other fibers included in this category?", "options": [{"label": "A", "text": "Hippocampal Commissure.", "correct": true}, {"label": "B", "text": "Fronto- occipital fasciculus.", "correct": false}, {"label": "C", "text": "Corona radiata.", "correct": false}, {"label": "D", "text": "Both A and C.", "correct": false}], "correct_answer": "A. Hippocampal Commissure.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392967969-QTDA068009IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Hippocampal Commissure. In the given question, the given MRI shows corpus callosum agenesis. It is a type of commissural fiber. The other commissural fiber in the given option will be option A. hippocampal commissure.</p>\n<p><strong>Highyeild:</strong></p><p>The habenular commissure, is a brain commissure (a band of nerve fibers) situated in front of the pineal gland that connects the habenular nuclei on both sides of the diencephalon.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Fronto-occipital fasciculus is a type of association fiber. Option: C. Corona radiata- it is a type of projection fiber. Option: D. Both A and C are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The habenular commissure is part of the habenular trigone (a small, depressed triangular area in front of the superior colliculus and on the lateral aspect of the posterior part of the tænia thalami). The trigonum habenulae also contain groups of nerve cells termed the ganglion habenulae. Fibers enter the trigonum habenulae from the stalk of the pineal gland and the habenular commissure.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "During your anatomy lecture in 1st year, your teacher taught you about the different types of commissural fibers present as cerebral white matter. Which of the following statements is not correct?", "options": [{"label": "A", "text": "Anterior commissure- runs in the basal forebrain and fans out laterally in the frontal lobe.", "correct": true}, {"label": "B", "text": "Corpus callosum is the largest commissural fiber.", "correct": false}, {"label": "C", "text": "Hippocampal commissure connects fornix.", "correct": false}, {"label": "D", "text": "Posterior commissure is present below the third ventricle's pineal recess and contains decussating and commissural fibers.", "correct": false}], "correct_answer": "A. Anterior commissure- runs in the basal forebrain and fans out laterally in the frontal lobe.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Anterior commissure- runs in the basal forebrain and fans out laterally in the frontal lobe. Anterior commissure runs in the basal forebrain and fans out laterally in the temporal lobe and not the frontal lobe. Hence, the incorrect statement is option A.</p>\n<p><strong>Highyeild:</strong></p><p>The anterior commissure connecting the archipallia (olfactory bulbs, piriform area, and anterior parts of temporal lobes) of the two sides .</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Corpus callosum is the largest commissural fiber is a true statement. Option: C. Hippocampal commissure connects fornix is a true statement. Option: D . Posterior commissure is present below the pineal recess of the third ventricle and contains both decussating and commissural fibers is also a true statement.</p>\n<p><strong>Extraedge:</strong></p><p>The posterior commissure, connecting the superior colliculi and also transmitting corticotectal fibers and fibers from the pretectal nucleus to the Edinger- Westphal nucleus of the opposite side.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were studying the orientation of the various nuclei in the basal ganglia and various white matter capsules around it. Arrange the following structure from lateral to medial as given in the options: Claustrum Extreme capsule Island of Reil External capsule Internal capsule Select the correct answer from the given below code:", "options": [{"label": "A", "text": "1->2->4->5->3", "correct": false}, {"label": "B", "text": "3->2->1->4->5", "correct": true}, {"label": "C", "text": "1->4->2->3->5", "correct": false}, {"label": "D", "text": "3->1->4->2->5", "correct": false}], "correct_answer": "B. 3->2->1->4->5", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>3->2->1->4->5 In the given question, the arrangement of structure from lateral to medial in the coronal section at the level of basal ganglia will be island of reil extreme capsule Claustrum external capsule internal capsule Components of the basal ganglia and its anatomical relations. Hence, the correct answer will be option B.</p>\n<p><strong>Highyeild:</strong></p><p>The term Basal nuclei is applied to a collection of masses of gray matter situated within each cerebral hemisphere. They are the corpus striatum, the amygdaloid nucleus, and the</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. 1->2->4->5->3 Option:C. 1->4->2->3->5 Option:D. 3->1->4->2->5 The arrangement of structure from lateral to medial in the coronal section at the level of basal ganglia will be : island of reil extreme capsule Claustrum external capsule internal capsule Therefore Options A, C and, D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>The subthalamic nuclei, the substantia nigra, and the red nucleus are functionally closely related to the basal nuclei.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were showing the following type of projection fiber. Which of the following blood vessels supply part A of the given structure?", "options": [{"label": "A", "text": "Recurrent artery of Huebner", "correct": true}, {"label": "B", "text": "Recurrent artery of Huebner and branch from MCA.", "correct": false}, {"label": "C", "text": "Branch from MCA and anterior choroidal artery.", "correct": false}, {"label": "D", "text": "Branches from posterior Cerebral artery.", "correct": false}], "correct_answer": "A. Recurrent artery of Huebner", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392968015-QTDA068012IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Recurrent artery of Huebner In the given question, the image is of an internal capsule which is a type of projection fiber. The part marked with A is the anterior limb of the internal capsule. It is supplied by the recurrent artery of Huebner which is a branch of the anterior cerebral artery.</p>\n<p><strong>Highyeild:</strong></p><p>Striate branches of the anterior cerebral artery. One of these branches is larger and takes a recurrent course. It is termed the recurrent artery of Huebner. It arises just proximal to the anterior communicating artery, runs superior to the optic chiasma and penetrates the anterior perforated substance to supply the genu and anterior limb of the internal capsule. Arteries supplying the internal capsule</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Recurrent artery of Huebner and branch from MCA- supplies the genu of the internal capsule. Medial and lateral striate branches of the middle cerebral artery. One of the lateral striate branches is larger and more frequently ruptured. It is often termed Charcot's artery of a cerebral haemorrhage. It enters through the anterior perforated substance and supplies the posterior limb of the internal capsule. Option: C. Branch from MCA and anterior choroidal artery- supplies the posterior limb of the internal capsule. Option: D. Branches from posterior cerebral artery supplies the posterior limb, retro and sub-lentiform nuclei of the internal capsule.</p>\n<p><strong>Extraedge:</strong></p><p>Involvement of recurrent artery of Huebner (due to thrombosis/rupture) results in paralysis of the face and upper limb on the opposite side (because of the involvement of corticonuclear fibers in the genu and adjacent pyramidal fibers in the posterior limb for the upper limb).</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Various tracts relay from the thalamus to the internal capsule, from where they reach their respective cortex. Which of the following parts of the internal capsule carries the ophthalmic radiation?", "options": [{"label": "A", "text": "Anterior Limb", "correct": false}, {"label": "B", "text": "Posterior limb", "correct": false}, {"label": "C", "text": "Retro-lentiform part", "correct": true}, {"label": "D", "text": "Sublentiform part.", "correct": false}], "correct_answer": "C. Retro-lentiform part", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Retro-lentiform part In the given question, the ophthalmic radiation, also known as posterior radiation, relays into the retro-lentiform part of the internal capsule, Hence, the answer will be option C. Fiber components of internal capsule</p>\n<p><strong>Highyeild:</strong></p><p>Pyramidal fibers arise in the cerebral cortex and relay in the lower motor neurons within the brainstem and spinal cord. The pyramidal fibers are of two types: Corticonuclear fibers synapse with the contralateral motor nuclei of the cranial nerves, which innervate the head and neck muscles. The corticonuclear fibers occupy the genu of the internal capsule. Corticospinal fibers synapse with the anterior horn cells of the opposite half of the spinal cord, which innervates the muscles of the upper limb, trunk, and lower limb. The corticospinal fibers form several discrete bundles in the anterior two-thirds of the posterior limb. The fibers for the upper limb are most anterior, followed in that order by the fibers for the trunk and the lower limb.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: A. Anterior limb- in this the anterior thalamic radiation relay. Option: B. Posterior limb- in this, superior thalamic radiation will relay. Option: D. sub-lentiform part- in this, inferior thalamic radiation relay into this.</p>\n<p><strong>Extraedge:</strong></p><p>Extrapyramidal fibers arise in the cerebral cortex and relay into the subcortical gray matter belonging to the extrapyramidal system ( red nucleus, corpus stria-tum, substantia nigra,), etc. They are named according to their destinations, viz . corticorubral, corticostriatal, corticonigral, etc., respectively. Most of the extrapyramidal fibers occupy the position near the corticospinal fibers in the internal capsule and are therefore affected by the lesions of the posterior limb.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "A 28-year-old male presented with weakness on the right side of the body in both the upper and lower limbs. From which part of the internal capsule, as marked in the given image, does the tract affected in this condition pass?", "options": [{"label": "A", "text": "b", "correct": false}, {"label": "B", "text": "c", "correct": true}, {"label": "C", "text": "a", "correct": false}, {"label": "D", "text": "d", "correct": false}], "correct_answer": "B. c", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686392968228-QTDA068014IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>c In the given question, as the patient has weakness in the right side of both the upper limbs and lower limbs, the pyramidal or the corticospinal tracts are affected in this patient. The corticospinal tract occupies the anterior 2/3 of the posterior limb. Hence, in the above image, t he posterior limb is marked by c.</p>\n<p><strong>Highyeild:</strong></p><p>Corticopontine fibers lie in the anterior limb, genu, and posterior limb. Frontopontine fibers start from the frontal lobe to reach the pontine nuclei, where these relay to reach opposite cerebellar hemispheres. These are called corticopontocerebellar fibers. Parietopontine and occipitopontine fibers lie in the retro-lentiform part of the internal capsule. Temporopontine fibers lie in the sub-lentiform part of the internal capsule.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option:A. b Option:C. a Option:D. d Other marked parts (in the given image): Anterior limb Genu Posterior limb Retro-lentiform part Sub-lentiform part. The corticospinal tract occupies the anterior 2/3 of the posterior limb. In the above image, the posterior limb is marked by c, therefore, options A, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>A lesion in the genu of the Internal Capsule Would produce a sensory and motor loss in the contra-lateral side of the head. This may not be complete since most cranial nerve nuclei have bilateral cortical innervation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 24 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">
Instructions
Test Features:
Multiple choice questions with single correct answers
Timer-based testing for realistic exam conditions
Mark questions for review functionality
Comprehensive results and performance analysis
Mobile-optimized interface for learning on-the-go
Start Test
<!-- Quiz Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="quiz"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <!-- Progress Bar --> <div class="w-full bg-gray-200 rounded-full h-3 mb-4"> <div class="progress-bar h-3 rounded-full" id="progress-bar" style="width: 0%"></div> </div> <!-- Question Header --> <div class="flex flex-col md:flex-row justify-between items-center mb-4"> <h2 class="text-lg font-semibold" id="question-number">Question <span>1</span> of 4</h2> <p class="text-lg font-semibold mt-2 md:mt-0" id="timer">Time Remaining: <span>00:00</span></p> </div> <!-- Question Content --> <div class="mb-6" id="question-content"> <p class="text-gray-800 mb-4" id="question-text"></p> <div class="flex flex-wrap gap-4 mb-4" id="question-images"></div> <div class="space-y-3" id="options"></div> </div> <!-- Navigation Buttons --> <div class="flex flex-col md:flex-row justify-between items-center gap-2 md:gap-4"> <div class="flex gap-2 w-full md:w-auto"> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="previous-btn">Previous</button> <button class="bg-[#2c5281] text-white px-4 py-3 w-full md:w-32 h-14 rounded-lg hover:bg-[#2c5281] transition" id="next-btn">Next</button> </div> <div class="flex items-center gap-2"> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="mark-review"> Review <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 2a1 1 0 00-1 1v14l3.293-3.293a1 1 0 011.414 0L17 17V3a1 1 0 00-1-1H10z" /> </svg> </button> <button class="bg-transparent text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-100 transition flex items-center gap-1" id="nav-toggle"> Question 🧭 </button> <button class="bg-green-500 text-white px-6 py-3 w-44 h-14 rounded-lg hover:bg-green-600 transition w-full md:w-auto" id="submit-test">Submit Test</button> </div> </div> </section> <!-- Results Section --> <section class="container mx-auto px-4 md:px-6 pt-4 md:pt-6 pb-1 hidden section-transition" id="results"> <div class="bg-white rounded-lg shadow-md p-4 md:p-6"> <h2 class="text-2xl font-semibold mb-4">Anaesthesia Machine - Results</h2> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> <p><strong>Correct:</strong> <span id="correct-count" class="text-[#000000]">0</span></p> <p><strong>Wrong:</strong> <span id="wrong-count" class="text-[#000000]">0</span></p> <p><strong>Unanswered:</strong> <span id="unanswered-count" class="text-[#000000]-500">0</span></p> <p><strong>Marked for Review:</strong> <span id="marked-count" class="text-[#000000]">0</span></p> </div> <h3 class="text-lg font-semibold mb-4" id="result-question-number">Question <span>1</span> of 4</h3> <div class="space-y-6" id="results-content"></div> <div class="result-nav"> <button aria-label="Previous question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" disabled="" id="prev-result">Previous</button> <button aria-label="Toggle results navigation panel" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="results-nav-toggle">Result 🧭</button> <button aria-label="Next question result" class="result-nav-btn bg-[#2c5281] text-white px-6 py-2 rounded-lg hover:bg-[#2c5281] transition" id="next-result">Next</button> </div> <div class="mt-6 flex space-x-4 button-group md:flex-row flex-col"> <button class="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600 transition" id="take-again">Take Again</button> </div> </div> </section> <!-- Exit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="exit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Leave Test?</h2> <p class="text-gray-700 mb-4">Your progress will be lost if you leave this page. Are you sure you want to exit?</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="continue-test">No, Continue</button> <button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition" id="exit-test">Yes, Exit</button> </div> </div> </div> <!-- Submit Confirmation Modal --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 hidden" id="submit-modal" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white rounded-lg p-6 max-w-sm w-full"> <h2 class="text-xl font-semibold mb-4">Confirm Submission</h2> <p class="text-gray-700 mb-2">You have attempted <span id="attempted-count">0</span> of 4 questions.</p> <p class="text-gray-700 mb-4"><span id="unattempted-count">0</span> questions are unattempted.</p> <div class="flex justify-end space-x-4"> <button class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition" id="cancel-submit">Cancel</button> <button class="text-white px-4 py-2 rounded-lg hover:bg-[#1a365d] transition" style="background-color: #2c5281;" id="confirm-submit">Submit Test</button> </div> </div> </div> <!-- Quiz Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 nav-panel hidden overflow-y-auto" id="nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Questions Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-nav">Close</button> </div> </div> <!-- Results Navigation Panel --> <div class="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center p-4 z-50 results-nav-panel hidden overflow-y-auto" id="results-nav-panel" style="align-items: flex-start; padding-top: 33vh;"> <div class="bg-white shadow-lg p-4 rounded-lg w-full max-w-2xl max-h-[80vh] overflow-y-auto"> <h2 class="text-lg font-semibold mb-4">Results Navigation</h2> <div class="mb-4"> <select class="w-full p-2 border rounded-lg text-gray-700" id="results-nav-filter"> <option value="all">All Questions</option> <option value="answered">Answered</option> <option value="unanswered">Unanswered</option> <option value="marked">Marked for Review</option> </select> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> </div> <div class="grid grid-cols-5 gap-2 md:gap-3" id="results-nav-grid"></div> <button class="mt-4 bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition w-full" id="close-results-nav">Close</button> </div> <!-- JavaScript Logic --> <script> // Enable debug mode for detailed logging const DEBUG_MODE = true; // Log debug messages function debugLog(message) { if (DEBUG_MODE) { console.log(`[DEBUG] ${message}`); } } // Initialize questions with error handling let questions = []; let currentResultQuestion = 0; // State for current question in results try { debugLog("Attempting to parse questions_json"); questions = [{"text": "Which of the following statements regarding the distribution of the descending tracts in the internal capsule is incorrect?", "options": [{"label": "A", "text": "Fronto-pontine fibers occupy the anterior limb, retro-lentiform, and the genu of the internal capsule.", "correct": true}, {"label": "B", "text": "Parieto-pontine fibers are present in the retro-lentiform part of the internal capsule.", "correct": false}, {"label": "C", "text": "Occipito-pontine fibers are present in the retro-lentiform part of the internal capsule.", "correct": false}, {"label": "D", "text": "Temporo-pontine fibers are present in the sub-lentiform part of the internal capsule.", "correct": false}], "correct_answer": "A. Fronto-pontine fibers occupy the anterior limb, retro-lentiform, and the genu of the internal capsule.", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Fronto-pontine fibers occupy the anterior limb, retro-lentiform, and the genu of the internal capsule. Fronto-pontine fibers relay in the internal capsule's anterior limb, genu, and posterior limb. Hence option A is not correct.</p>\n<p><strong>Highyeild:</strong></p><p>Constituent motor and sensory fibers in different parts of the internal capsule Part Descending tracts Ascending tracts Arterial supply Anterior limb Frontopontine fibres (a part of the corticopontocerebellar pathway) Anterior thalamic radiation (fibres from anterior and medial nuclei of thalamus) 1. Recurrent branch of anterior cerebral 2. Direct branches from anterior cerebral Genu Corticonuclear fibres (a part of the pyramidal tract going to motor nuclei of cranial nerves and forming their supranuclear pathway) Anterior part of the superior thalamic radiation (fibres from posterior ventral nucleus of thalamus) 1. Direct branches from internal carotid 2. Posterior communicating Posterior limb 1. Corticospinal tract (pyramidal tract for the upper limb, trunk and lower limb) 2. Corticopontine fibres 3. Corticorubral fibres 1. Superior thalamic radiation 2. Fibres from globus pallidus to subthalamic nucleus 1. Lateral striate branches of middle cerebral 2. Medial striate branches of middle cerebral 3. Anterior choroidal Sublentiform part 1. Parietopontine and temporopontine fibres 2. Fibres between temporal lobe and thalamus 1. Auditory radiation 2. Fibres connecting thalamus to temporal lobe 1. Branches of posterior cerebral 2. Anterior choroidal Retrolentiform part 1. Parietopontine and occipitopontine fibres Retrolentiform part 2. Fibres from occipital cortex to superior colliculus and pretectal region Posterior thalamic radiation made up of: 1. Mainly optic radiation 2. Partly fibres connecting thalamus to the parietal and occipital lobes Branches of posterior cerebral</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. Parieto-pontine fibers, present in the retro-lentiform part of the internal capsule, is a correct statement. Option: C. Occipito-pontine fibers are present in the retro-lentiform part of the internal capsule is a correct statement. Option: D. Temporo-pontine fibers are present in the sub-lentiform part of the internal capsule is a correct statement.</p>\n<p><strong>Extraedge:</strong></p><p>Inferior thalamic radiation is directed inferiorly. Its fibers pass through the sub-lentiform part of the internal capsule. Most connect the medial geniculate body with the primary auditory area of the temporal lobe forming auditory radiation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "Which of the following statements regarding the given fibers in the MR is- tractography correct? It originates from the precentral gyrus. They fan throughout the corona radiata and converge towards the internal capsule anterior limb and genu. Additionally, cortico-rubral fibers are also present in the internal capsule. They decussate at the level of the spinal cord.", "options": [{"label": "A", "text": "A, C, D", "correct": false}, {"label": "B", "text": "A, C", "correct": true}, {"label": "C", "text": "A, B, C, D", "correct": false}, {"label": "D", "text": "B, D", "correct": false}], "correct_answer": "B. A, C", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393002143-QTDA069002IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>A, C In the given question, MR- tractography shows the corticospinal fiber originating from the precentral gyrus (option A is correct). In the anterior, 2/3 of the posterior limb, it also contains cortico-rubral fiber. (option C is correct)</p>\n<p><strong>Highyeild:</strong></p><p>Fibers of Internal Capsule (Motor fibers) Corticopontine fibers lie in the anterior limb, genu, and posterior limb. Frontopontine fibers start from the frontal lobe to reach the pontine nuclei, which relay to opposite cerebellar hemispheres. These are called corticoponto- cerebellar fibers. Parieto Pontine and Occipito Pontine fibers lie in the retro-lentiform part of the internal capsule. Temporopontine fibers lie in the sub-lentiform part of the internal capsule. Pyramidal fibers Pyramidal fibers arise in the cerebral cortex and relay to the lower motor neurons within the brainstem and spinal cord. Corticonuclear fibers synapse with the contralateral motor nuclei of the cranial nerves, which innervate the head and neck muscles. The corticonuclear fibers occupy the genu of the internal capsule. Corticospinal : Fibers for anterior horn cells of head and neck muscles lie in genu. Fibers for the upper, trunk, and lower limbs lie in the posterior limb of the internal capsule in sequential order. Extrapyramidal fibers These fibers start from the cerebral cortex as corticostriatal and corticorubral fibers and reach the corpus striatum and red nucleus.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option:A. A, C, D Option:C. A, B, C, D Option:D. B, D They fan throughout the corona radiata and converge towards the internal capsule genu and posterior limb, not the anterior limb (option B is wrong). It decussates at the lower medulla (hence, option D is wrong). Therefore Options A, C, and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Fibers of Internal Capsule (Sensory fibers) Thalamocortical fibers form thalamic radiations (3rd order neuron fibers): Anterior thalamic radiation: Fibers from the anterior and dorsomedial nuclei of the thalamus terminate in the cortex of the frontal lobe. Superior thalamic radiation: Fibers of the ventral group of nuclei of the thalamus reach sensory areas of the frontal and parietal lobes. Inferior thalamic radiation : Connect the medial geniculate body with the primary auditory cortex. Posterior thalamic radiation: These fibers connect the lateral geniculate body to area 17, forming optic radiation.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "You were posted in an emergency where a 58-year-old male complained of sudden weakness on the left side of his body. The doctor on duty tells you about the anatomical basis as the pyramidal tracts are affected, which passes from the internal capsule. Which of the following structures does not lie medially to the internal capsule?", "options": [{"label": "A", "text": "Caudate Nucleus.", "correct": false}, {"label": "B", "text": "Lentiform nuclei", "correct": true}, {"label": "C", "text": "Corpus callosum", "correct": false}, {"label": "D", "text": "Thalamus.", "correct": false}], "correct_answer": "B. Lentiform nuclei", "question_images": [], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Lentiform nuclei In the given question, as asked, the structure which does not lie medially to the internal capsule is lentiform nuclei. It lies laterally in the internal capsule. Hence, the answer to this question will be option B. Internal capsule parts and relation</p>\n<p><strong>Highyeild:</strong></p><p>The internal capsule is a compact bundle of projection fibers between the thalamus and caudate nucleus medially and the lentiform nucleus laterally. These fibers fan out rostrally to form the corona radiata and condense caudally to continue as the crus cerebri of the midbrain. The internal capsule ascending (corticopetal/sensory) and descending (corticofugal/motor) fibers chiefly interconnect the cerebral cortex with the brainstem and spinal cord. These fibers are mainly responsible for the sensory and motor innervation of the opposite half of the body.</p>\n<p><strong>Random:</strong></p><p>Explanation For Incorrect Options: - Option:A. Caudate Nucleus. Option:C. Corpus callosum Option:D. Thalamus. Other options lie medially in the internal capsule.</p>\n<p><strong>Extraedge:</strong></p><p>Because of the high concentration of motor and sensory nerve fibers within the internal capsule, even a small lesion may produce widespread paralytic effects and sensory loss in the opposite half of the body.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The following image is shown in a neurology seminar. You were asked about the pathway which originates from the structure marked with stars and from which part of the internal capsule passes. Your answer will be.", "options": [{"label": "A", "text": "Auditory pathway, retro-lentiform part of the internal capsule.", "correct": false}, {"label": "B", "text": "Visual pathway, sub-lentiform part of the internal capsule", "correct": false}, {"label": "C", "text": "Auditory pathway, sub-lentiform part of the internal capsule.", "correct": true}, {"label": "D", "text": "Visual pathway, retro-lentiform part of the internal capsule.", "correct": false}], "correct_answer": "C. Auditory pathway, sub-lentiform part of the internal capsule.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393002730-QTDA069005IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Auditory pathway, sub-lentiform part of the internal capsule. In the given question, the marked structure from the star is the medial geniculate body, which gives origin to the auditory pathway. The auditory pathway passes from the sub-lentiform part of the internal capsule. Hence, the correct answer to this question is option C.</p>\n<p><strong>Highyeild:</strong></p><p>Lesions of the internal capsule are usually vascular due to the involvement of the middle cerebral artery's medial and lateral striate branches. They give rise to hemiplegia on the opposite half of the body (paralysis of one-half of the body, including the face). It is an upper motor neuron type of paralysis. The larger lateral striate artery is called ‘Charcot’s artery of a cerebral hemorrhage.’</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. Auditory pathway, retro-lentiform part of the internal capsule. In the given question, the marked structure from the star is the medial geniculate body, which gives origin to the auditory pathway. The auditory pathway passes from the sub-lentiform part of the internal capsule. Option:B. Visual pathway, sub-lentiform part of the internal capsule Option:D. Visual pathway, retro-lentiform part of the internal capsule. The visual pathway comes from the lateral geniculate body and passes from the retro-lentiform part of the internal capsule. Therefore, both B and D are incorrect answers.</p>\n<p><strong>Extraedge:</strong></p><p>Thrombosis of the recurrent branch of the anterior cerebral artery gives rise to an upper motor neuron type of paralysis of the opposite upper limb and of the face.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "The given structure in the image was shown to you during your medicine lecture on neurology. Which of the following statements is not correct regarding this?", "options": [{"label": "A", "text": "The given structure originates from the mammillary body.", "correct": true}, {"label": "B", "text": "The two crura of the marked part are joined via the fibers that cross in the commissure of the fornix.", "correct": false}, {"label": "C", "text": "It is the main outflow bundle of the hippocampus that wraps around the thalamus.", "correct": false}, {"label": "D", "text": "It consists of association as well as commissural fibers.", "correct": false}], "correct_answer": "A. The given structure originates from the mammillary body.", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393003102-QTDA069006IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>The given structure originates from the mammillary body. The given structure marked in the cross-section of the brain is known as fornix, which originates from the hippocampus and terminates in the mammillary body. Hence the incorrect statement in this question is option A.</p>\n<p><strong>Highyeild:</strong></p><p>Papez circuit</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option: B. The two crura of the marked part are joined via the fibers that cross in the commissure of the fornix is true. Option: C. It is the main outflow bundle of the hippocampus that wraps around the thalamus from which the choroid fissure separates it. Option: D . It consists of association as well as commissural fibers. Commissural fibers are present only in hippocampal commissures.</p>\n<p><strong>Extraedge:</strong></p><p>Olfactory tracts</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}, {"text": "While studying neurology basics, you came across the following cross-section image. The marked structure gives rise to which tract facilitates flexors and inhibits extensors. From which part of the internal capsule does this tract pass?", "options": [{"label": "A", "text": "Anterior Limb", "correct": false}, {"label": "B", "text": "Genu", "correct": false}, {"label": "C", "text": "Posterior limb", "correct": true}, {"label": "D", "text": "Sublentiform part", "correct": false}], "correct_answer": "C. Posterior limb", "question_images": ["https://dbmi-data.s3.ap-south-1.amazonaws.com/photos-1686393003326-QTDA069007IMG1.JPG"], "explanation_images": [], "explanation": "<p><strong>Solution:</strong></p><p>Posterior limb In the given question, the structure marked is the red nucleus which gives rise to the rubrospinal tract, which facilitates flexors and inhibits extensors. The part of this tract that will pass from the internal capsule is the cortico-rubral tract. It will pass from the anterior 2/3 of the posterior limb. Hence the correct answer will be option C.</p>\n<p><strong>Highyeild:</strong></p><p>The red nucleus or nucleus ruber is a structure in the rostral midbrain involved in motor coordination. The red nucleus is pale pink, which is believed to be due to the presence of iron in at least two different forms: hemoglobin and ferritin. The structure is located in the tegmentum of the midbrain next to the substantia nigra and comprises caudal magnocellular and rostral parvocellular components. The red nucleus and substantia nigra are subcortical centers of the extrapyramidal motor system.</p>\n<p><strong>Random:</strong></p><p>Explanation for incorrect options: - Option:A. Anterior limb- Majorly fronto-pontine fibers pass from this. Option:B. Genu of the internal capsule- from this cortico-nuclear tract and fronto-pontine fibers passes. Option:D . Sublentiform part- temporo-pontine fibers pass from this part. The red nucleus receives many inputs from the cerebellum ( interposed nucleus and the lateral cerebellar nucleus) of the opposite side and input from the motor cortex of the same side.</p>\n<p><strong>Extraedge:</strong></p><p>The red nucleus receives many inputs from the cerebellum ( interposed nucleus and the lateral cerebellar nucleus) of the opposite side and input from the motor cortex of the same side. The red nucleus has two sets of efferents: In humans, most of the output goes to the bundle of fibers that continues through the medial tegmental field toward the inferior olive of the same side to form part of a pathway that ultimately influences the cerebellum . The other output (the rubrospinal projection) goes to the opposite rhombencephalic reticular formation and spinal cord, making up the rubrospinal tract , which runs ventrally to the lateral corticospinal tract . As stated earlier, the rubrospinal tract is more important in non-primate species. In primates , because of the well-developed cerebral cortex, the corticospinal tract has taken over the role of the rubrospinal.</p>\n<p>@dams_new_robot</p>", "bot": "@dams_new_robot", "video": ""}]; if (!Array.isArray(questions) || questions.length === 0) { throw new Error("Questions data is empty or invalid"); } debugLog(`Successfully parsed ${questions.length} questions`); } catch (e) { console.error("Failed to parse questions_json:", e); document.getElementById('error-message').innerHTML = "Error loading quiz data. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; // Fallback to sample questions for testing questions = [ { text: "What is 2 + 2?", options: [ { label: "A", text: "3", correct: false }, { label: "B", text: "4", correct: true }, { label: "C", text: "5", correct: false }, { label: "D", text: "6", correct: false } ], correct_answer: "B. 4", question_images: [], explanation_images: [], explanation: "<p>2 + 2 = 4</p><p>@dams_new_robot</p>", bot: "@dams_new_robot", audio: "", video: "" } ]; debugLog("Loaded fallback questions"); } // Quiz state let currentQuestion = 0; let answers = new Array(questions.length).fill(null); let markedForReview = new Array(questions.length).fill(false); let timeRemaining = 16 * 60; // Duration in seconds let timerInterval = null; const quizId = `{title.replace(/\s+/g, '_').toLowerCase()}`; // Unique ID for local storage // Load saved progress function loadProgress() { try { debugLog("Loading progress from localStorage"); const saved = localStorage.getItem(`quiz_${quizId}`); if (saved) { const { savedAnswers, savedMarked, savedTime } = JSON.parse(saved); answers = savedAnswers || answers; markedForReview = savedMarked || markedForReview; timeRemaining = savedTime !== undefined ? savedTime : timeRemaining; debugLog("Progress loaded successfully"); } else { debugLog("No saved progress found"); } } catch (e) { console.error("Error loading progress:", e); debugLog("Failed to load progress: " + e.message); } } // Save progress function saveProgress() { try { debugLog("Saving progress to localStorage"); localStorage.setItem(`quiz_${quizId}`, JSON.stringify({ savedAnswers: answers, savedMarked: markedForReview, savedTime: timeRemaining })); debugLog("Progress saved successfully"); } catch (e) { console.error("Error saving progress:", e); debugLog("Failed to save progress: " + e.message); } } // Initialize quiz function initQuiz() { try { debugLog("Initializing quiz"); loadProgress(); const startButton = document.getElementById('start-test'); if (!startButton) { throw new Error("Start test button not found"); } startButton.addEventListener('click', startQuiz); debugLog("Start test button listener attached"); document.getElementById('previous-btn').addEventListener('click', showPreviousQuestion); document.getElementById('next-btn').addEventListener('click', showNextQuestion); document.getElementById('mark-review').addEventListener('click', toggleMarkForReview); document.getElementById('nav-toggle').addEventListener('click', toggleNavPanel); document.getElementById('submit-test').addEventListener('click', showSubmitModal); document.getElementById('continue-test').addEventListener('click', closeExitModal); document.getElementById('exit-test').addEventListener('click', () => { debugLog("Exiting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('cancel-submit').addEventListener('click', closeSubmitModal); document.getElementById('confirm-submit').addEventListener('click', submitTest); document.getElementById('take-again').addEventListener('click', () => { debugLog("Restarting test"); localStorage.removeItem(`quiz_${quizId}`); window.location.reload(); }); document.getElementById('review-test').addEventListener('click', () => showResults(currentResultQuestion)); document.getElementById('close-nav').addEventListener('click', toggleNavPanel); document.getElementById('theme-toggle').addEventListener('click', toggleTheme); document.getElementById('nav-filter').addEventListener('change', updateNavPanel); document.getElementById('prev-result').addEventListener('click', showPreviousResult); document.getElementById('next-result').addEventListener('click', showNextResult); document.getElementById('results-nav-toggle').addEventListener('click', toggleResultsNavPanel); document.getElementById('close-results-nav').addEventListener('click', toggleResultsNavPanel); document.getElementById('results-nav-filter').addEventListener('change', updateResultsNavPanel); debugLog("Quiz initialized successfully"); } catch (e) { console.error("Failed to initialize quiz:", e); debugLog("Failed to initialize quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('start-test').disabled = true; } } // Start quiz function startQuiz() { try { debugLog("Starting quiz"); document.getElementById('instructions').classList.add('hidden'); document.getElementById('quiz').classList.remove('hidden'); showQuestion(currentQuestion); startTimer(); updateNavPanel(); debugLog("Quiz started successfully"); } catch (e) { console.error("Error starting quiz:", e); debugLog("Failed to start quiz: " + e.message); document.getElementById('error-message').innerHTML = "Error starting quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); document.getElementById('quiz').classList.add('hidden'); document.getElementById('instructions').classList.remove('hidden'); } } // Show question function showQuestion(index) { try { debugLog(`Showing question ${index + 1}`); currentQuestion = index; const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } document.getElementById('question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('question-text').innerHTML = q.text || "No question text available"; const imagesDiv = document.getElementById('question-images'); imagesDiv.innerHTML = q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg">`).join('') : ''; const optionsDiv = document.getElementById('options'); optionsDiv.innerHTML = q.options && q.options.length > 0 ? q.options.map(opt => ` <button class="option-btn w-full text-left p-3 border rounded-lg ${answers[index] === opt.label ? 'selected' : ''}" onclick="selectOption(${index}, '${opt.label}')" aria-label="Option ${opt.label}: ${opt.text}"> ${opt.label}. ${opt.text} </button> `).join('') : '<p class="text-red-500">No options available</p>'; document.getElementById('previous-btn').disabled = index === 0; document.getElementById('next-btn').disabled = index === questions.length - 1; document.getElementById('mark-review').classList.toggle('marked', markedForReview[index]); updateProgressBar(); saveProgress(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying question:", e); debugLog("Failed to display question: " + e.message); } } // Select option function selectOption(index, label) { try { debugLog(`Selecting option ${label} for question ${index + 1}`); answers[index] = label; const optionsDiv = document.getElementById('options'); const optionButtons = optionsDiv.querySelectorAll('.option-btn'); optionButtons.forEach(btn => { const btnLabel = btn.textContent.trim().split('.')[0]; btn.classList.toggle('selected', btnLabel === label); }); updateNavPanel(); saveProgress(); debugLog(`Option ${label} selected for question ${index + 1}`); } catch (e) { console.error("Error selecting option:", e); debugLog("Failed to select option: " + e.message); } } // Toggle mark for review function toggleMarkForReview() { try { debugLog(`Toggling mark for review on question ${currentQuestion + 1}`); markedForReview[currentQuestion] = !markedForReview[currentQuestion]; document.getElementById('mark-review').classList.toggle('marked', markedForReview[currentQuestion]); updateNavPanel(); saveProgress(); debugLog(`Mark for review toggled for question ${currentQuestion + 1}`); } catch (e) { console.error("Error marking for review:", e); debugLog("Failed to mark for review: " + e.message); } } // Navigate to previous question function showPreviousQuestion() { try { debugLog(`Navigating to previous question from ${currentQuestion + 1}`); if (currentQuestion > 0) { currentQuestion--; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to previous question:", e); debugLog("Failed to navigate to previous question: " + e.message); } } // Navigate to next question function showNextQuestion() { try { debugLog(`Navigating to next question from ${currentQuestion + 1}`); if (currentQuestion < questions.length - 1) { currentQuestion++; showQuestion(currentQuestion); } } catch (e) { console.error("Error navigating to next question:", e); debugLog("Failed to navigate to next question: " + e.message); } } // Handle question navigation click function handleQuestionNavClick(index) { try { debugLog(`Navigating to question ${index + 1} via nav panel`); showQuestion(index); toggleNavPanel(); } catch (e) { console.error("Error handling navigation click:", e); debugLog("Failed to navigate via nav panel: " + e.message); } } // Start timer function startTimer() { try { debugLog("Starting timer"); timerInterval = setInterval(() => { if (timeRemaining <= 0) { debugLog("Timer expired, submitting test"); clearInterval(timerInterval); submitTest(); } else { timeRemaining--; const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; document.getElementById('timer').innerHTML = `Time Remaining: <span>${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}</span>`; saveProgress(); } }, 1000); debugLog("Timer started successfully"); } catch (e) { console.error("Error starting timer:", e); debugLog("Failed to start timer: " + e.message); } } // Update progress bar function updateProgressBar() { try { debugLog("Updating progress bar"); const progress = ((currentQuestion + 1) / questions.length) * 100; document.getElementById('progress-bar').style.width = `${progress}%`; debugLog("Progress bar updated"); } catch (e) { console.error("Error updating progress bar:", e); debugLog("Failed to update progress bar: " + e.message); } } // Update quiz navigation panel function updateNavPanel() { try { debugLog("Updating quiz navigation panel"); const filter = document.getElementById('nav-filter').value; const navGrid = document.getElementById('nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="question-nav-btn ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleQuestionNavClick(${i})" aria-label="Go to Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Quiz navigation panel updated"); } catch (e) { console.error("Error updating quiz navigation panel:", e); debugLog("Failed to update quiz navigation panel: " + e.message); } } // Update results navigation panel function updateResultsNavPanel() { try { debugLog("Updating results navigation panel"); const filter = document.getElementById('results-nav-filter').value; const navGrid = document.getElementById('results-nav-grid'); navGrid.innerHTML = questions.map((_, i) => { if (filter === 'answered' && !answers[i]) return ''; if (filter === 'unanswered' && answers[i]) return ''; if (filter === 'marked' && !markedForReview[i]) return ''; return ` <button class="result-nav-btn-grid ${answers[i] ? 'answered' : 'unanswered'} ${markedForReview[i] ? 'marked-nav' : ''}" onclick="handleResultNavClick(${i})" aria-label="Go to Result for Question ${i + 1}"> ${i + 1} </button> `; }).join(''); debugLog("Results navigation panel updated"); } catch (e) { console.error("Error updating results navigation panel:", e); debugLog("Failed to update results navigation panel: " + e.message); } } // Toggle quiz navigation panel function toggleNavPanel() { try { debugLog("Toggling quiz navigation panel"); const navPanel = document.getElementById('nav-panel'); navPanel.classList.toggle('hidden'); debugLog("Quiz navigation panel toggled"); } catch (e) { console.error("Error toggling quiz navigation panel:", e); debugLog("Failed to toggle quiz navigation panel: " + e.message); } } // Toggle results navigation panel function toggleResultsNavPanel() { try { debugLog("Toggling results navigation panel"); const resultsNavPanel = document.getElementById('results-nav-panel'); resultsNavPanel.classList.toggle('hidden'); if (!resultsNavPanel.classList.contains('hidden')) { updateResultsNavPanel(); } debugLog("Results navigation panel toggled"); } catch (e) { console.error("Error toggling results navigation panel:", e); debugLog("Failed to toggle results navigation panel: " + e.message); } } // Handle result navigation click function handleResultNavClick(index) { try { debugLog(`Navigating to result for question ${index + 1} via nav panel`); showResults(index); toggleResultsNavPanel(); } catch (e) { console.error("Error handling result navigation click:", e); debugLog("Failed to navigate to result: " + e.message); } } // Show submit modal function showSubmitModal() { try { debugLog("Showing submit modal"); const attempted = answers.filter(a => a !== null).length; document.getElementById('attempted-count').textContent = attempted; document.getElementById('unattempted-count').textContent = questions.length - attempted; document.getElementById('submit-modal').classList.remove('hidden'); debugLog("Submit modal displayed"); } catch (e) { console.error("Error showing submit modal:", e); debugLog("Failed to show submit modal: " + e.message); } } // Close submit modal function closeSubmitModal() { try { debugLog("Closing submit modal"); document.getElementById('submit-modal').classList.add('hidden'); debugLog("Submit modal closed"); } catch (e) { console.error("Error closing submit modal:", e); debugLog("Failed to close submit modal: " + e.message); } } // Close exit modal function closeExitModal() { try { debugLog("Closing exit modal"); document.getElementById('exit-modal').classList.add('hidden'); debugLog("Exit modal closed"); } catch (e) { console.error("Error closing exit modal:", e); debugLog("Failed to close exit modal: " + e.message); } } // Submit test function submitTest() { try { debugLog("Submitting test"); clearInterval(timerInterval); document.getElementById('quiz').classList.add('hidden'); document.getElementById('submit-modal').classList.add('hidden'); document.getElementById('results').classList.remove('hidden'); showResults(0); // Start with first question // Trigger confetti animation confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); localStorage.removeItem(`quiz_${quizId}`); debugLog("Test submitted successfully"); } catch (e) { console.error("Error submitting test:", e); debugLog("Failed to submit test: " + e.message); } } // Show result for a single question function showResults(index) { try { debugLog(`Showing result for question ${index + 1}`); currentResultQuestion = index; let correct = 0, wrong = 0, unanswered = 0, marked = 0; answers.forEach((answer, i) => { const isCorrect = answer && questions[i].options.find(opt => opt.label === answer)?.correct; if (answer === null) unanswered++; else if (isCorrect) correct++; else wrong++; if (markedForReview[i]) marked++; }); const q = questions[index]; if (!q) { throw new Error(`Question ${index} is undefined`); } const userAnswer = answers[index]; const isCorrect = userAnswer && q.options.find(opt => opt.label === userAnswer)?.correct; const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = ` <div class="border p-4 rounded-lg ${isCorrect ? 'bg-green-50' : userAnswer ? 'bg-red-50' : 'bg-gray-50'}"> <p class="font-semibold">Question ${index + 1}: ${q.text || 'No question text'}</p> ${q.question_images && q.question_images.length > 0 ? q.question_images.map(url => `<img src="${url}" alt="Question Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} <p><strong>Your Answer:</strong> ${userAnswer ? `${userAnswer}. ${q.options.find(opt => opt.label === userAnswer)?.text || 'Invalid option'}` : 'Unanswered'}</p> <p><strong>Correct Answer:</strong> ${q.correct_answer || 'Unknown'}</p> <div class="mt-2">${q.explanation || 'No explanation available'}</div> ${q.explanation_images && q.explanation_images.length > 0 ? q.explanation_images.map(url => `<img src="${url}" alt="Explanation Image" class="max-w-full h-auto rounded-lg my-2">`).join('') : ''} ${q.video ? ` <button class="play-video bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadVideo(this, '${q.video}', 'video-${index}')" aria-label="Play explanation video for Question ${index + 1}"> Play Video Explanation </button> <div id="video-${index}" class="video-container mt-2"></div> ` : '<p class="text-gray-500 mt-2">No video available</p>'} ${q.audio ? ` <button class="play-audio bg-blue-500 text-white px-4 py-2 rounded-lg mt-2" onclick="loadAudio(this, '${q.audio}', 'audio-${index}')" aria-label="Play audio explanation for Question ${index + 1}"> Play Audio Explanation </button> <div id="audio-${index}" class="audio-container mt-2"></div> ` : ''} </div> `; document.getElementById('correct-count').textContent = correct; document.getElementById('wrong-count').textContent = wrong; document.getElementById('unanswered-count').textContent = unanswered; document.getElementById('marked-count').textContent = marked; document.getElementById('result-question-number').innerHTML = `Question <span>${index + 1}</span> of ${questions.length}`; document.getElementById('prev-result').disabled = index === 0; document.getElementById('next-result').disabled = index === questions.length - 1; updateResultsNavPanel(); window.scrollTo({ top: 0, behavior: 'smooth' }); debugLog(`Result for question ${index + 1} displayed successfully`); } catch (e) { console.error("Error displaying result:", e); debugLog("Failed to display result: " + e.message); } } // Navigate to previous result function showPreviousResult() { try { debugLog(`Navigating to previous result from question ${currentResultQuestion + 1}`); if (currentResultQuestion > 0) { showResults(currentResultQuestion - 1); } } catch (e) { console.error("Error navigating to previous result:", e); debugLog("Failed to navigate to previous result: " + e.message); } } // Navigate to next result function showNextResult() { try { debugLog(`Navigating to next result from question ${currentResultQuestion + 1}`); if (currentResultQuestion < questions.length - 1) { showResults(currentResultQuestion + 1); } } catch (e) { console.error("Error navigating to next result:", e); debugLog("Failed to navigate to next result: " + e.message); } } // Lazy-load video function loadVideo(button, videoUrl, containerId) { try { debugLog(`Loading video for ${containerId}: ${videoUrl}`); if (!videoUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No video available</p>`; button.remove(); debugLog("No video URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <div class="video-loading"></div> <video controls class="w-full max-w-[600px] rounded-lg" preload="metadata" aria-label="Video explanation"> <source src="${videoUrl}" type="${videoUrl.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'}"> Your browser does not support the video tag. </video> `; container.classList.add('active'); button.remove(); // Initialize HLS.js for .m3u8 videos const video = container.querySelector('video'); if (videoUrl.endsWith('.m3u8') && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(videoUrl); hls.attachMedia(video); hls.on(Hls.Events.ERROR, (event, data) => { console.error("HLS.js error:", data); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("HLS.js error: " + JSON.stringify(data)); }); } else if (videoUrl.endsWith('.m3u8') && video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoUrl; } // Handle video load errors video.onerror = () => { console.error("Video load error for URL:", videoUrl); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; debugLog("Video load error for URL: " + videoUrl); }; // Remove loading spinner when video is ready video.onloadedmetadata = () => { container.querySelector('.video-loading').remove(); debugLog("Video loaded successfully"); }; } catch (e) { console.error("Error loading video:", e); debugLog("Failed to load video: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading video. <a href="${videoUrl}" target="_blank" aria-label="Open video in new tab">Open video</a></p>`; } } // Lazy-load audio function loadAudio(button, audioUrl, containerId) { try { debugLog(`Loading audio for ${containerId}: ${audioUrl}`); if (!audioUrl) { const container = document.getElementById(containerId); container.innerHTML = `<p class="text-gray-500">No audio available</p>`; button.remove(); debugLog("No audio URL provided"); return; } const container = document.getElementById(containerId); container.innerHTML = ` <audio controls class="w-full max-w-[600px]" preload="metadata" aria-label="Audio explanation"> <source src="${audioUrl}" type="audio/mpeg"> Your browser does not support the audio tag. </audio> `; container.classList.add('active'); button.remove(); // Handle audio load errors const audio = container.querySelector('audio'); audio.onerror = () => { console.error("Audio load error for URL:", audioUrl); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; debugLog("Audio load error for URL: " + audioUrl); }; debugLog("Audio loaded successfully"); } catch (e) { console.error("Error loading audio:", e); debugLog("Failed to load audio: " + e.message); const container = document.getElementById(containerId); container.innerHTML = `<p class="text-red-500">Error loading audio. <a href="${audioUrl}" target="_blank" aria-label="Open audio in new tab">Open audio</a></p>`; } } // Toggle dark mode function toggleTheme() { try { debugLog("Toggling theme"); document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); debugLog("Theme toggled successfully"); } catch (e) { console.error("Error toggling theme:", e); debugLog("Failed to toggle theme: " + e.message); } } // Load theme preference function loadTheme() { try { debugLog("Loading theme preference"); const theme = localStorage.getItem('theme'); if (theme === 'dark') { document.documentElement.classList.add('dark'); } debugLog("Theme loaded successfully"); } catch (e) { console.error("Error loading theme:", e); debugLog("Failed to load theme: " + e.message); } } // Initialize on DOM content loaded window.addEventListener('DOMContentLoaded', () => { try { debugLog("DOM content loaded, initializing quiz"); loadTheme(); initQuiz(); } catch (e) { console.error("Error during DOMContentLoaded:", e); debugLog("Failed to initialize on DOMContentLoaded: " + e.message); document.getElementById('error-message').innerHTML = "Error initializing quiz. Please check the console for details or contact support."; document.getElementById('error-message').classList.remove('hidden'); } }); </script> </body> </html>" frameborder="0" width="100%" height="2000px">